• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package com.android.server.pm;
17 
18 import static android.Manifest.permission.DELETE_PACKAGES;
19 import static android.Manifest.permission.INSTALL_PACKAGES;
20 import static android.Manifest.permission.MANAGE_DEVICE_ADMINS;
21 import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
22 import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
23 import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS;
24 import static android.app.AppOpsManager.MODE_DEFAULT;
25 import static android.app.AppOpsManager.MODE_IGNORED;
26 import static android.content.Intent.ACTION_MAIN;
27 import static android.content.Intent.CATEGORY_DEFAULT;
28 import static android.content.Intent.CATEGORY_HOME;
29 import static android.content.Intent.EXTRA_LONG_VERSION_CODE;
30 import static android.content.Intent.EXTRA_PACKAGE_NAME;
31 import static android.content.Intent.EXTRA_VERSION_CODE;
32 import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509;
33 import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
34 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
35 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
36 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
37 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
38 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
39 import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ID;
40 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
41 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
42 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
43 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
44 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
45 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
46 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
47 import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_PERMISSION_GROUP;
48 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
49 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
50 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION_GROUP;
51 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
52 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
53 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
54 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
55 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
56 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
57 import static android.content.pm.PackageManager.INSTALL_FAILED_PROCESS_NOT_DEFINED;
58 import static android.content.pm.PackageManager.INSTALL_FAILED_SESSION_INVALID;
59 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
60 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
61 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
62 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
63 import static android.content.pm.PackageManager.INSTALL_INTERNAL;
64 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
65 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
66 import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_RESTORE;
67 import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_SETUP;
68 import static android.content.pm.PackageManager.INSTALL_STAGED;
69 import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
70 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
71 import static android.content.pm.PackageManager.MATCH_ALL;
72 import static android.content.pm.PackageManager.MATCH_ANY_USER;
73 import static android.content.pm.PackageManager.MATCH_APEX;
74 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
75 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
76 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
77 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
78 import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
79 import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
80 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
81 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
82 import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
83 import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
84 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
85 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
86 import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
87 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
88 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
89 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
90 import static android.content.pm.PackageManager.RESTRICTION_NONE;
91 import static android.content.pm.PackageManager.TYPE_ACTIVITY;
92 import static android.content.pm.PackageManager.TYPE_PROVIDER;
93 import static android.content.pm.PackageManager.TYPE_RECEIVER;
94 import static android.content.pm.PackageManager.TYPE_SERVICE;
95 import static android.content.pm.PackageManager.TYPE_UNKNOWN;
96 import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN;
97 import static android.content.pm.PackageManagerInternal.LAST_KNOWN_PACKAGE;
98 import static android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4;
99 import static android.content.pm.parsing.ApkLiteParseUtils.isApkFile;
100 import static android.os.PowerWhitelistManager.REASON_LOCKED_BOOT_COMPLETED;
101 import static android.os.PowerWhitelistManager.REASON_PACKAGE_REPLACED;
102 import static android.os.PowerWhitelistManager.REASON_PACKAGE_VERIFIER;
103 import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
104 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
105 import static android.os.incremental.IncrementalManager.isIncrementalPath;
106 import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
107 import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
108 import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
109 import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE;
110 
111 import static com.android.internal.annotations.VisibleForTesting.Visibility;
112 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
113 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
114 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
115 import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME;
116 import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_INIT_TIME;
117 import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME;
118 import static com.android.server.pm.ComponentResolver.RESOLVE_PRIORITY_SORTER;
119 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
120 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
121 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
122 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
123 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
124 import static com.android.server.pm.PackageManagerServiceUtils.comparePackageSignatures;
125 import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
126 import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
127 import static com.android.server.pm.PackageManagerServiceUtils.decompressFile;
128 import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
129 import static com.android.server.pm.PackageManagerServiceUtils.dumpCriticalInfo;
130 import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFiles;
131 import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
132 import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
133 import static com.android.server.pm.PackageManagerServiceUtils.makeDirRecursive;
134 import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
135 
136 import android.Manifest;
137 import android.annotation.AppIdInt;
138 import android.annotation.IntDef;
139 import android.annotation.NonNull;
140 import android.annotation.Nullable;
141 import android.annotation.StringRes;
142 import android.annotation.UserIdInt;
143 import android.annotation.WorkerThread;
144 import android.app.ActivityManager;
145 import android.app.ActivityManagerInternal;
146 import android.app.AppOpsManager;
147 import android.app.ApplicationPackageManager;
148 import android.app.BroadcastOptions;
149 import android.app.IActivityManager;
150 import android.app.ResourcesManager;
151 import android.app.admin.IDevicePolicyManager;
152 import android.app.admin.SecurityLog;
153 import android.app.backup.IBackupManager;
154 import android.app.role.RoleManager;
155 import android.compat.annotation.ChangeId;
156 import android.compat.annotation.EnabledAfter;
157 import android.content.BroadcastReceiver;
158 import android.content.ComponentName;
159 import android.content.ContentResolver;
160 import android.content.Context;
161 import android.content.IIntentReceiver;
162 import android.content.Intent;
163 import android.content.IntentFilter;
164 import android.content.IntentSender;
165 import android.content.IntentSender.SendIntentException;
166 import android.content.PermissionChecker;
167 import android.content.pm.ActivityInfo;
168 import android.content.pm.ApplicationInfo;
169 import android.content.pm.AuxiliaryResolveInfo;
170 import android.content.pm.ChangedPackages;
171 import android.content.pm.Checksum;
172 import android.content.pm.ComponentInfo;
173 import android.content.pm.DataLoaderType;
174 import android.content.pm.FallbackCategoryProvider;
175 import android.content.pm.FeatureInfo;
176 import android.content.pm.IDexModuleRegisterCallback;
177 import android.content.pm.IOnChecksumsReadyListener;
178 import android.content.pm.IPackageChangeObserver;
179 import android.content.pm.IPackageDataObserver;
180 import android.content.pm.IPackageDeleteObserver;
181 import android.content.pm.IPackageDeleteObserver2;
182 import android.content.pm.IPackageInstallObserver2;
183 import android.content.pm.IPackageInstaller;
184 import android.content.pm.IPackageLoadingProgressCallback;
185 import android.content.pm.IPackageManager;
186 import android.content.pm.IPackageManagerNative;
187 import android.content.pm.IPackageMoveObserver;
188 import android.content.pm.IPackageStatsObserver;
189 import android.content.pm.IncrementalStatesInfo;
190 import android.content.pm.InstallSourceInfo;
191 import android.content.pm.InstantAppInfo;
192 import android.content.pm.InstantAppRequest;
193 import android.content.pm.InstantAppResolveInfo.InstantAppDigest;
194 import android.content.pm.InstrumentationInfo;
195 import android.content.pm.IntentFilterVerificationInfo;
196 import android.content.pm.KeySet;
197 import android.content.pm.ModuleInfo;
198 import android.content.pm.PackageChangeEvent;
199 import android.content.pm.PackageInfo;
200 import android.content.pm.PackageInfoLite;
201 import android.content.pm.PackageInstaller;
202 import android.content.pm.PackageManager;
203 import android.content.pm.PackageManager.ComponentType;
204 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
205 import android.content.pm.PackageManager.ModuleInfoFlags;
206 import android.content.pm.PackageManager.Property;
207 import android.content.pm.PackageManager.PropertyLocation;
208 import android.content.pm.PackageManagerInternal;
209 import android.content.pm.PackageManagerInternal.PackageListObserver;
210 import android.content.pm.PackageManagerInternal.PrivateResolveFlags;
211 import android.content.pm.PackageParser;
212 import android.content.pm.PackageParser.PackageParserException;
213 import android.content.pm.PackageParser.SigningDetails;
214 import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
215 import android.content.pm.PackagePartitions;
216 import android.content.pm.PackagePartitions.SystemPartition;
217 import android.content.pm.PackageStats;
218 import android.content.pm.PackageUserState;
219 import android.content.pm.ParceledListSlice;
220 import android.content.pm.PermissionGroupInfo;
221 import android.content.pm.PermissionInfo;
222 import android.content.pm.ProcessInfo;
223 import android.content.pm.ProviderInfo;
224 import android.content.pm.ResolveInfo;
225 import android.content.pm.SELinuxUtil;
226 import android.content.pm.ServiceInfo;
227 import android.content.pm.SharedLibraryInfo;
228 import android.content.pm.Signature;
229 import android.content.pm.SigningInfo;
230 import android.content.pm.SuspendDialogInfo;
231 import android.content.pm.TestUtilityService;
232 import android.content.pm.UserInfo;
233 import android.content.pm.VerifierDeviceIdentity;
234 import android.content.pm.VerifierInfo;
235 import android.content.pm.VersionedPackage;
236 import android.content.pm.dex.ArtManager;
237 import android.content.pm.dex.DexMetadataHelper;
238 import android.content.pm.dex.IArtManager;
239 import android.content.pm.overlay.OverlayPaths;
240 import android.content.pm.parsing.ApkLiteParseUtils;
241 import android.content.pm.parsing.PackageLite;
242 import android.content.pm.parsing.ParsingPackageUtils;
243 import android.content.pm.parsing.ParsingPackageUtils.ParseFlags;
244 import android.content.pm.parsing.component.ParsedActivity;
245 import android.content.pm.parsing.component.ParsedInstrumentation;
246 import android.content.pm.parsing.component.ParsedMainComponent;
247 import android.content.pm.parsing.component.ParsedPermission;
248 import android.content.pm.parsing.component.ParsedPermissionGroup;
249 import android.content.pm.parsing.component.ParsedProcess;
250 import android.content.pm.parsing.component.ParsedProvider;
251 import android.content.pm.parsing.component.ParsedService;
252 import android.content.pm.parsing.result.ParseResult;
253 import android.content.pm.parsing.result.ParseTypeImpl;
254 import android.content.res.Resources;
255 import android.database.ContentObserver;
256 import android.graphics.Bitmap;
257 import android.hardware.display.DisplayManager;
258 import android.net.Uri;
259 import android.os.Binder;
260 import android.os.Build;
261 import android.os.Bundle;
262 import android.os.Environment;
263 import android.os.FileUtils;
264 import android.os.Handler;
265 import android.os.HandlerExecutor;
266 import android.os.HandlerThread;
267 import android.os.IBinder;
268 import android.os.Looper;
269 import android.os.Message;
270 import android.os.Parcel;
271 import android.os.ParcelableException;
272 import android.os.PatternMatcher;
273 import android.os.PersistableBundle;
274 import android.os.PowerWhitelistManager;
275 import android.os.Process;
276 import android.os.RemoteCallbackList;
277 import android.os.RemoteException;
278 import android.os.ResultReceiver;
279 import android.os.SELinux;
280 import android.os.ServiceManager;
281 import android.os.ShellCallback;
282 import android.os.SystemClock;
283 import android.os.SystemProperties;
284 import android.os.Trace;
285 import android.os.UserHandle;
286 import android.os.UserManager;
287 import android.os.incremental.IncrementalManager;
288 import android.os.incremental.IncrementalStorage;
289 import android.os.incremental.PerUidReadTimeouts;
290 import android.os.storage.DiskInfo;
291 import android.os.storage.IStorageManager;
292 import android.os.storage.StorageEventListener;
293 import android.os.storage.StorageManager;
294 import android.os.storage.StorageManagerInternal;
295 import android.os.storage.VolumeInfo;
296 import android.os.storage.VolumeRecord;
297 import android.permission.PermissionManager;
298 import android.provider.ContactsContract;
299 import android.provider.DeviceConfig;
300 import android.provider.Settings.Global;
301 import android.provider.Settings.Secure;
302 import android.security.KeyStore;
303 import android.security.SystemKeyStore;
304 import android.service.pm.PackageServiceDumpProto;
305 import android.stats.storage.StorageEnums;
306 import android.system.ErrnoException;
307 import android.system.Os;
308 import android.text.TextUtils;
309 import android.text.format.DateUtils;
310 import android.util.ArrayMap;
311 import android.util.ArraySet;
312 import android.util.Base64;
313 import android.util.DisplayMetrics;
314 import android.util.EventLog;
315 import android.util.ExceptionUtils;
316 import android.util.IntArray;
317 import android.util.Log;
318 import android.util.LogPrinter;
319 import android.util.LongSparseLongArray;
320 import android.util.MathUtils;
321 import android.util.PackageUtils;
322 import android.util.Pair;
323 import android.util.PrintStreamPrinter;
324 import android.util.Slog;
325 import android.util.SparseArray;
326 import android.util.SparseBooleanArray;
327 import android.util.SparseIntArray;
328 import android.util.TimingsTraceLog;
329 import android.util.TypedXmlPullParser;
330 import android.util.TypedXmlSerializer;
331 import android.util.Xml;
332 import android.util.apk.ApkSignatureVerifier;
333 import android.util.jar.StrictJarFile;
334 import android.util.proto.ProtoOutputStream;
335 import android.view.Display;
336 
337 import com.android.internal.R;
338 import com.android.internal.annotations.GuardedBy;
339 import com.android.internal.annotations.VisibleForTesting;
340 import com.android.internal.app.ResolverActivity;
341 import com.android.internal.content.F2fsUtils;
342 import com.android.internal.content.NativeLibraryHelper;
343 import com.android.internal.content.PackageHelper;
344 import com.android.internal.content.om.OverlayConfig;
345 import com.android.internal.logging.MetricsLogger;
346 import com.android.internal.os.SomeArgs;
347 import com.android.internal.policy.AttributeCache;
348 import com.android.internal.security.VerityUtils;
349 import com.android.internal.telephony.CarrierAppUtils;
350 import com.android.internal.util.ArrayUtils;
351 import com.android.internal.util.CollectionUtils;
352 import com.android.internal.util.ConcurrentUtils;
353 import com.android.internal.util.DumpUtils;
354 import com.android.internal.util.FrameworkStatsLog;
355 import com.android.internal.util.FunctionalUtils;
356 import com.android.internal.util.IndentingPrintWriter;
357 import com.android.internal.util.Preconditions;
358 import com.android.permission.persistence.RuntimePermissionsPersistence;
359 import com.android.server.DeviceIdleInternal;
360 import com.android.server.EventLogTags;
361 import com.android.server.FgThread;
362 import com.android.server.LocalServices;
363 import com.android.server.LockGuard;
364 import com.android.server.PackageWatchdog;
365 import com.android.server.ServiceThread;
366 import com.android.server.SystemConfig;
367 import com.android.server.SystemServerInitThreadPool;
368 import com.android.server.Watchdog;
369 import com.android.server.apphibernation.AppHibernationManagerInternal;
370 import com.android.server.apphibernation.AppHibernationService;
371 import com.android.server.compat.CompatChange;
372 import com.android.server.compat.PlatformCompat;
373 import com.android.server.net.NetworkPolicyManagerInternal;
374 import com.android.server.pm.Installer.InstallerException;
375 import com.android.server.pm.Settings.DatabaseVersion;
376 import com.android.server.pm.Settings.VersionInfo;
377 import com.android.server.pm.dex.ArtManagerService;
378 import com.android.server.pm.dex.ArtUtils;
379 import com.android.server.pm.dex.DexManager;
380 import com.android.server.pm.dex.DexoptOptions;
381 import com.android.server.pm.dex.PackageDexUsage;
382 import com.android.server.pm.dex.ViewCompiler;
383 import com.android.server.pm.parsing.PackageCacher;
384 import com.android.server.pm.parsing.PackageInfoUtils;
385 import com.android.server.pm.parsing.PackageParser2;
386 import com.android.server.pm.parsing.library.PackageBackwardCompatibility;
387 import com.android.server.pm.parsing.pkg.AndroidPackage;
388 import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
389 import com.android.server.pm.parsing.pkg.PackageImpl;
390 import com.android.server.pm.parsing.pkg.ParsedPackage;
391 import com.android.server.pm.permission.LegacyPermissionManagerInternal;
392 import com.android.server.pm.permission.LegacyPermissionManagerService;
393 import com.android.server.pm.permission.Permission;
394 import com.android.server.pm.permission.PermissionManagerService;
395 import com.android.server.pm.permission.PermissionManagerServiceInternal;
396 import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
397 import com.android.server.pm.verify.domain.DomainVerificationService;
398 import com.android.server.pm.verify.domain.DomainVerificationUtils;
399 import com.android.server.pm.verify.domain.proxy.DomainVerificationProxy;
400 import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyV1;
401 import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyV2;
402 import com.android.server.rollback.RollbackManagerInternal;
403 import com.android.server.storage.DeviceStorageMonitorInternal;
404 import com.android.server.uri.UriGrantsManagerInternal;
405 import com.android.server.utils.SnapshotCache;
406 import com.android.server.utils.TimingsTraceAndSlog;
407 import com.android.server.utils.Watchable;
408 import com.android.server.utils.Watched;
409 import com.android.server.utils.WatchedArrayMap;
410 import com.android.server.utils.WatchedLongSparseArray;
411 import com.android.server.utils.WatchedSparseBooleanArray;
412 import com.android.server.utils.WatchedSparseIntArray;
413 import com.android.server.utils.Watcher;
414 import com.android.server.wm.ActivityTaskManagerInternal;
415 
416 import dalvik.system.CloseGuard;
417 import dalvik.system.VMRuntime;
418 
419 import libcore.io.IoUtils;
420 import libcore.util.EmptyArray;
421 import libcore.util.HexEncoding;
422 
423 import org.xmlpull.v1.XmlPullParser;
424 import org.xmlpull.v1.XmlPullParserException;
425 
426 import java.io.BufferedOutputStream;
427 import java.io.ByteArrayInputStream;
428 import java.io.ByteArrayOutputStream;
429 import java.io.File;
430 import java.io.FileDescriptor;
431 import java.io.FileInputStream;
432 import java.io.FileOutputStream;
433 import java.io.IOException;
434 import java.io.InputStream;
435 import java.io.PrintWriter;
436 import java.lang.annotation.ElementType;
437 import java.lang.annotation.Retention;
438 import java.lang.annotation.RetentionPolicy;
439 import java.lang.annotation.Target;
440 import java.nio.charset.StandardCharsets;
441 import java.security.DigestException;
442 import java.security.DigestInputStream;
443 import java.security.MessageDigest;
444 import java.security.NoSuchAlgorithmException;
445 import java.security.PublicKey;
446 import java.security.SecureRandom;
447 import java.security.cert.Certificate;
448 import java.security.cert.CertificateException;
449 import java.security.cert.CertificateFactory;
450 import java.security.cert.X509Certificate;
451 import java.util.ArrayList;
452 import java.util.Arrays;
453 import java.util.Collection;
454 import java.util.Collections;
455 import java.util.Comparator;
456 import java.util.HashMap;
457 import java.util.HashSet;
458 import java.util.Iterator;
459 import java.util.LinkedHashSet;
460 import java.util.List;
461 import java.util.Map;
462 import java.util.Objects;
463 import java.util.Set;
464 import java.util.UUID;
465 import java.util.concurrent.CompletableFuture;
466 import java.util.concurrent.CountDownLatch;
467 import java.util.concurrent.Executor;
468 import java.util.concurrent.ExecutorService;
469 import java.util.concurrent.Future;
470 import java.util.concurrent.TimeUnit;
471 import java.util.concurrent.atomic.AtomicBoolean;
472 import java.util.concurrent.atomic.AtomicInteger;
473 import java.util.function.BiConsumer;
474 import java.util.function.Consumer;
475 import java.util.function.Function;
476 import java.util.function.Predicate;
477 
478 /**
479  * Keep track of all those APKs everywhere.
480  * <p>
481  * Internally there are three important locks:
482  * <ul>
483  * <li>{@link #mLock} is used to guard all in-memory parsed package details
484  * and other related state. It is a fine-grained lock that should only be held
485  * momentarily, as it's one of the most contended locks in the system.
486  * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
487  * operations typically involve heavy lifting of application data on disk. Since
488  * {@code installd} is single-threaded, and it's operations can often be slow,
489  * this lock should never be acquired while already holding {@link #mLock}.
490  * Conversely, it's safe to acquire {@link #mLock} momentarily while already
491  * holding {@link #mInstallLock}.
492  * <li>{@link #mSnapshotLock} is used to guard access to two snapshot fields: the snapshot
493  * itself and the snapshot invalidation flag.  This lock should never be acquired while
494  * already holding {@link #mLock}. Conversely, it's safe to acquire {@link #mLock}
495  * momentarily while already holding {@link #mSnapshotLock}.
496  * </ul>
497  * Many internal methods rely on the caller to hold the appropriate locks, and
498  * this contract is expressed through method name suffixes:
499  * <ul>
500  * <li>fooLI(): the caller must hold {@link #mInstallLock}
501  * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
502  * being modified must be frozen
503  * <li>fooLPr(): the caller must hold {@link #mLock} for reading
504  * <li>fooLPw(): the caller must hold {@link #mLock} for writing
505  * </ul>
506  * {@link #mSnapshotLock} is taken in exactly one place - {@code snapshotComputer()}.  It
507  * should not be taken anywhere else or used for any other purpose.
508  * <p>
509  * Because this class is very central to the platform's security; please run all
510  * CTS and unit tests whenever making modifications:
511  *
512  * <pre>
513  * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
514  * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
515  * </pre>
516  */
517 public class PackageManagerService extends IPackageManager.Stub
518         implements PackageSender, TestUtilityService {
519     static final String TAG = "PackageManager";
520     public static final boolean DEBUG_SETTINGS = false;
521     static final boolean DEBUG_PREFERRED = false;
522     static final boolean DEBUG_UPGRADE = false;
523     static final boolean DEBUG_DOMAIN_VERIFICATION = false;
524     private static final boolean DEBUG_BACKUP = false;
525     public static final boolean DEBUG_INSTALL = false;
526     public static final boolean DEBUG_REMOVE = false;
527     private static final boolean DEBUG_BROADCASTS = false;
528     private static final boolean DEBUG_PACKAGE_INFO = false;
529     private static final boolean DEBUG_INTENT_MATCHING = false;
530     public static final boolean DEBUG_PACKAGE_SCANNING = false;
531     private static final boolean DEBUG_VERIFY = false;
532     public static final boolean DEBUG_PERMISSIONS = false;
533     private static final boolean DEBUG_SHARED_LIBRARIES = false;
534     public static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
535     public static final boolean TRACE_SNAPSHOTS = false;
536     private static final boolean DEBUG_PER_UID_READ_TIMEOUTS = false;
537 
538     // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
539     // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
540     // user, but by default initialize to this.
541     public static final boolean DEBUG_DEXOPT = false;
542 
543     static final boolean DEBUG_ABI_SELECTION = false;
544     private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE;
545     private static final boolean DEBUG_APP_DATA = false;
546 
547     /** REMOVE. According to Svet, this was only used to reset permissions during development. */
548     static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
549 
550     private static final boolean HIDE_EPHEMERAL_APIS = false;
551 
552     private static final String PRECOMPILE_LAYOUTS = "pm.precompile_layouts";
553 
554     private static final int RADIO_UID = Process.PHONE_UID;
555     private static final int LOG_UID = Process.LOG_UID;
556     private static final int NFC_UID = Process.NFC_UID;
557     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
558     private static final int SHELL_UID = Process.SHELL_UID;
559     private static final int SE_UID = Process.SE_UID;
560     private static final int NETWORKSTACK_UID = Process.NETWORK_STACK_UID;
561     private static final int UWB_UID = Process.UWB_UID;
562 
563     static final int SCAN_NO_DEX = 1 << 0;
564     static final int SCAN_UPDATE_SIGNATURE = 1 << 1;
565     static final int SCAN_NEW_INSTALL = 1 << 2;
566     static final int SCAN_UPDATE_TIME = 1 << 3;
567     static final int SCAN_BOOTING = 1 << 4;
568     static final int SCAN_REQUIRE_KNOWN = 1 << 7;
569     static final int SCAN_MOVE = 1 << 8;
570     static final int SCAN_INITIAL = 1 << 9;
571     static final int SCAN_DONT_KILL_APP = 1 << 10;
572     static final int SCAN_IGNORE_FROZEN = 1 << 11;
573     static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1 << 12;
574     static final int SCAN_AS_INSTANT_APP = 1 << 13;
575     static final int SCAN_AS_FULL_APP = 1 << 14;
576     static final int SCAN_AS_VIRTUAL_PRELOAD = 1 << 15;
577     static final int SCAN_AS_SYSTEM = 1 << 16;
578     static final int SCAN_AS_PRIVILEGED = 1 << 17;
579     static final int SCAN_AS_OEM = 1 << 18;
580     static final int SCAN_AS_VENDOR = 1 << 19;
581     static final int SCAN_AS_PRODUCT = 1 << 20;
582     static final int SCAN_AS_SYSTEM_EXT = 1 << 21;
583     static final int SCAN_AS_ODM = 1 << 22;
584     static final int SCAN_AS_APK_IN_APEX = 1 << 23;
585 
586     @IntDef(flag = true, prefix = { "SCAN_" }, value = {
587             SCAN_NO_DEX,
588             SCAN_UPDATE_SIGNATURE,
589             SCAN_NEW_INSTALL,
590             SCAN_UPDATE_TIME,
591             SCAN_BOOTING,
592             SCAN_REQUIRE_KNOWN,
593             SCAN_MOVE,
594             SCAN_INITIAL,
595             SCAN_DONT_KILL_APP,
596             SCAN_IGNORE_FROZEN,
597             SCAN_FIRST_BOOT_OR_UPGRADE,
598             SCAN_AS_INSTANT_APP,
599             SCAN_AS_FULL_APP,
600             SCAN_AS_VIRTUAL_PRELOAD,
601     })
602     @Retention(RetentionPolicy.SOURCE)
603     public @interface ScanFlags {}
604 
605     /**
606      * Used as the result code of the {@link #getPackageStartability}.
607      */
608     @IntDef(value = {
609         PACKAGE_STARTABILITY_OK,
610         PACKAGE_STARTABILITY_NOT_FOUND,
611         PACKAGE_STARTABILITY_NOT_SYSTEM,
612         PACKAGE_STARTABILITY_FROZEN,
613         PACKAGE_STARTABILITY_DIRECT_BOOT_UNSUPPORTED,
614     })
615     @Retention(RetentionPolicy.SOURCE)
616     public @interface PackageStartability {}
617 
618     /**
619      * Used as the result code of the {@link #getPackageStartability} to indicate
620      * the given package is allowed to start.
621      */
622     static final int PACKAGE_STARTABILITY_OK = 0;
623 
624     /**
625      * Used as the result code of the {@link #getPackageStartability} to indicate
626      * the given package is <b>not</b> allowed to start because it's not found
627      * (could be due to that package is invisible to the given user).
628      */
629     static final int PACKAGE_STARTABILITY_NOT_FOUND = 1;
630 
631     /**
632      * Used as the result code of the {@link #getPackageStartability} to indicate
633      * the given package is <b>not</b> allowed to start because it's not a system app
634      * and the system is running in safe mode.
635      */
636     static final int PACKAGE_STARTABILITY_NOT_SYSTEM = 2;
637 
638     /**
639      * Used as the result code of the {@link #getPackageStartability} to indicate
640      * the given package is <b>not</b> allowed to start because it's currently frozen.
641      */
642     static final int PACKAGE_STARTABILITY_FROZEN = 3;
643 
644     /**
645      * Used as the result code of the {@link #getPackageStartability} to indicate
646      * the given package is <b>not</b> allowed to start because it doesn't support
647      * direct boot.
648      */
649     static final int PACKAGE_STARTABILITY_DIRECT_BOOT_UNSUPPORTED = 4;
650 
651     private static final String STATIC_SHARED_LIB_DELIMITER = "_";
652     /** Extension of the compressed packages */
653     public final static String COMPRESSED_EXTENSION = ".gz";
654     /** Suffix of stub packages on the system partition */
655     public final static String STUB_SUFFIX = "-Stub";
656 
657     private static final int[] EMPTY_INT_ARRAY = new int[0];
658 
659     /**
660      * Timeout (in milliseconds) after which the watchdog should declare that
661      * our handler thread is wedged.  The usual default for such things is one
662      * minute but we sometimes do very lengthy I/O operations on this thread,
663      * such as installing multi-gigabyte applications, so ours needs to be longer.
664      */
665     static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
666 
667     /**
668      * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
669      * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
670      * settings entry if available, otherwise we use the hardcoded default.  If it's been
671      * more than this long since the last fstrim, we force one during the boot sequence.
672      *
673      * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
674      * one gets run at the next available charging+idle time.  This final mandatory
675      * no-fstrim check kicks in only of the other scheduling criteria is never met.
676      */
677     private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
678 
679     /**
680      * Whether verification is enabled by default.
681      */
682     private static final boolean DEFAULT_VERIFY_ENABLE = true;
683 
684     /**
685      * Whether integrity verification is enabled by default.
686      */
687     private static final boolean DEFAULT_INTEGRITY_VERIFY_ENABLE = true;
688 
689     /**
690      * The default maximum time to wait for the verification agent to return in
691      * milliseconds.
692      */
693     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
694 
695     /**
696      * The default maximum time to wait for the integrity verification to return in
697      * milliseconds.
698      */
699     private static final long DEFAULT_INTEGRITY_VERIFICATION_TIMEOUT = 30 * 1000;
700 
701     /**
702      * Timeout duration in milliseconds for enabling package rollback. If we fail to enable
703      * rollback within that period, the install will proceed without rollback enabled.
704      *
705      * <p>If flag value is negative, the default value will be assigned.
706      *
707      * Flag type: {@code long}
708      * Namespace: NAMESPACE_ROLLBACK
709      */
710     private static final String PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS = "enable_rollback_timeout";
711 
712     /**
713      * The default duration to wait for rollback to be enabled in
714      * milliseconds.
715      */
716     private static final long DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS = 10 * 1000;
717 
718     /**
719      * Default IncFs timeouts. Maximum values in IncFs is 1hr.
720      *
721      * <p>If flag value is empty, the default value will be assigned.
722      *
723      * Flag type: {@code String}
724      * Namespace: NAMESPACE_PACKAGE_MANAGER_SERVICE
725      */
726     private static final String PROPERTY_INCFS_DEFAULT_TIMEOUTS = "incfs_default_timeouts";
727 
728     /**
729      * Known digesters with optional timeouts.
730      *
731      * Flag type: {@code String}
732      * Namespace: NAMESPACE_PACKAGE_MANAGER_SERVICE
733      */
734     private static final String PROPERTY_KNOWN_DIGESTERS_LIST = "known_digesters_list";
735 
736     /**
737      * The default response for package verification timeout.
738      *
739      * This can be either PackageManager.VERIFICATION_ALLOW or
740      * PackageManager.VERIFICATION_REJECT.
741      */
742     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
743 
744     /**
745      * Adding an installer package name to a package that does not have one set requires the
746      * INSTALL_PACKAGES permission.
747      *
748      * If the caller targets R, this will throw a SecurityException. Otherwise the request will
749      * fail silently. In both cases, and regardless of whether this change is enabled, the
750      * installer package will remain unchanged.
751      */
752     @ChangeId
753     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
754     private static final long THROW_EXCEPTION_ON_REQUIRE_INSTALL_PACKAGES_TO_ADD_INSTALLER_PACKAGE =
755             150857253;
756 
757     /**
758      * Apps targeting Android S and above need to declare dependencies to the public native
759      * shared libraries that are defined by the device maker using {@code uses-native-library} tag
760      * in its {@code AndroidManifest.xml}.
761      *
762      * If any of the dependencies cannot be satisfied, i.e. one of the dependency doesn't exist,
763      * the package manager rejects to install the app. The dependency can be specified as optional
764      * using {@code android:required} attribute in the tag, in which case failing to satisfy the
765      * dependency doesn't stop the installation.
766      * <p>Once installed, an app is provided with only the native shared libraries that are
767      * specified in the app manifest. {@code dlopen}ing a native shared library that doesn't appear
768      * in the app manifest will fail even if it actually exists on the device.
769      */
770     @ChangeId
771     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R)
772     private static final long ENFORCE_NATIVE_SHARED_LIBRARY_DEPENDENCIES = 142191088;
773 
774     public static final String PLATFORM_PACKAGE_NAME = "android";
775 
776     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
777 
778     private static final String PACKAGE_SCHEME = "package";
779 
780     private static final String COMPANION_PACKAGE_NAME = "com.android.companiondevicemanager";
781 
782     // Compilation reasons.
783     public static final int REASON_FIRST_BOOT = 0;
784     public static final int REASON_BOOT_AFTER_OTA = 1;
785     public static final int REASON_POST_BOOT = 2;
786     public static final int REASON_INSTALL = 3;
787     public static final int REASON_INSTALL_FAST = 4;
788     public static final int REASON_INSTALL_BULK = 5;
789     public static final int REASON_INSTALL_BULK_SECONDARY = 6;
790     public static final int REASON_INSTALL_BULK_DOWNGRADED = 7;
791     public static final int REASON_INSTALL_BULK_SECONDARY_DOWNGRADED = 8;
792     public static final int REASON_BACKGROUND_DEXOPT = 9;
793     public static final int REASON_AB_OTA = 10;
794     public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 11;
795     public static final int REASON_CMDLINE = 12;
796     public static final int REASON_SHARED = 13;
797 
798     public static final int REASON_LAST = REASON_SHARED;
799 
800     /**
801      * The initial enabled state of the cache before other checks are done.
802      */
803     private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
804 
805     /**
806      * Whether to skip all other checks and force the cache to be enabled.
807      *
808      * Setting this to true will cause the cache to be named "debug" to avoid eviction from
809      * build fingerprint changes.
810      */
811     private static final boolean FORCE_PACKAGE_PARSED_CACHE_ENABLED = false;
812 
813     /**
814      * Permissions required in order to receive instant application lifecycle broadcasts.
815      */
816     private static final String[] INSTANT_APP_BROADCAST_PERMISSION =
817             new String[] { android.Manifest.permission.ACCESS_INSTANT_APPS };
818 
819     private static final String RANDOM_DIR_PREFIX = "~~";
820 
821     final Handler mHandler;
822 
823     private final ProcessLoggingHandler mProcessLoggingHandler;
824 
825     private final boolean mEnableFreeCacheV2;
826 
827     final int mSdkVersion;
828     final Context mContext;
829     final boolean mFactoryTest;
830     final boolean mOnlyCore;
831     final DisplayMetrics mMetrics;
832     final int mDefParseFlags;
833     final String[] mSeparateProcesses;
834     final boolean mIsUpgrade;
835     final boolean mIsPreNUpgrade;
836     final boolean mIsPreNMR1Upgrade;
837     final boolean mIsPreQUpgrade;
838 
839     @GuardedBy("mLock")
840     private boolean mDexOptDialogShown;
841 
842     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
843     // LOCK HELD.  Can be called with mInstallLock held.
844     @GuardedBy("mInstallLock")
845     final Installer mInstaller;
846 
847     /** Directory where installed applications are stored */
848     private final File mAppInstallDir;
849     /** Directory where installed application's 32-bit native libraries are copied. */
850     @VisibleForTesting
851     final File mAppLib32InstallDir;
852 
getAppLib32InstallDir()853     private static File getAppLib32InstallDir() {
854         return new File(Environment.getDataDirectory(), "app-lib");
855     }
856 
857     // ----------------------------------------------------------------
858 
859     // Lock for state used when installing and doing other long running
860     // operations.  Methods that must be called with this lock held have
861     // the suffix "LI".
862     final Object mInstallLock;
863 
864     // ----------------------------------------------------------------
865 
866     // Lock for global state used when modifying package state or settings.
867     // Methods that must be called with this lock held have
868     // the suffix "Locked". Some methods may use the legacy suffix "LP"
869     final PackageManagerTracedLock mLock;
870 
871     // Keys are String (package name), values are Package.
872     @Watched
873     @GuardedBy("mLock")
874     final WatchedArrayMap<String, AndroidPackage> mPackages = new WatchedArrayMap<>();
875     private final SnapshotCache<WatchedArrayMap<String, AndroidPackage>> mPackagesSnapshot =
876             new SnapshotCache.Auto(mPackages, mPackages, "PackageManagerService.mPackages");
877 
878     // Keys are isolated uids and values are the uid of the application
879     // that created the isolated process.
880     @Watched
881     @GuardedBy("mLock")
882     final WatchedSparseIntArray mIsolatedOwners = new WatchedSparseIntArray();
883     private final SnapshotCache<WatchedSparseIntArray> mIsolatedOwnersSnapshot =
884             new SnapshotCache.Auto(mIsolatedOwners, mIsolatedOwners,
885                                    "PackageManagerService.mIsolatedOwners");
886 
887     /**
888      * Tracks new system packages [received in an OTA] that we expect to
889      * find updated user-installed versions. Keys are package name, values
890      * are package location.
891      */
892     final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
893 
894     /**
895      * Tracks existing packages prior to receiving an OTA. Keys are package name.
896      * Only non-null during an OTA, and even then it is nulled again once systemReady().
897      */
898     private @Nullable ArraySet<String> mExistingPackages = null;
899 
900     /**
901      * List of code paths that need to be released when the system becomes ready.
902      * <p>
903      * NOTE: We have to delay releasing cblocks for no other reason than we cannot
904      * retrieve the setting {@link Secure#RELEASE_COMPRESS_BLOCKS_ON_INSTALL}. When
905      * we no longer need to read that setting, cblock release can occur in the
906      * constructor.
907      *
908      * @see Secure#RELEASE_COMPRESS_BLOCKS_ON_INSTALL
909      * @see #systemReady()
910      */
911     private @Nullable List<File> mReleaseOnSystemReady;
912 
913     /**
914      * Whether or not system app permissions should be promoted from install to runtime.
915      */
916     boolean mPromoteSystemApps;
917 
918     private final PackageManagerInternal mPmInternal;
919     private final TestUtilityService mTestUtilityService;
920 
921 
922     @Watched
923     @GuardedBy("mLock")
924     final Settings mSettings;
925 
926     /**
927      * Set of package names that are currently "frozen", which means active
928      * surgery is being done on the code/data for that package. The platform
929      * will refuse to launch frozen packages to avoid race conditions.
930      *
931      * @see PackageFreezer
932      */
933     @GuardedBy("mLock")
934     final ArraySet<String> mFrozenPackages = new ArraySet<>();
935 
936     final ProtectedPackages mProtectedPackages;
937 
938     @GuardedBy("mLoadedVolumes")
939     final ArraySet<String> mLoadedVolumes = new ArraySet<>();
940 
941     boolean mFirstBoot;
942 
943     private final boolean mIsEngBuild;
944     private final boolean mIsUserDebugBuild;
945     private final String mIncrementalVersion;
946 
947 
948     PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
949 
950     @GuardedBy("mAvailableFeatures")
951     final ArrayMap<String, FeatureInfo> mAvailableFeatures;
952 
953     @Watched
954     private final InstantAppRegistry mInstantAppRegistry;
955 
956     @GuardedBy("mLock")
957     int mChangedPackagesSequenceNumber;
958     /**
959      * List of changed [installed, removed or updated] packages.
960      * mapping from user id -> sequence number -> package name
961      */
962     @GuardedBy("mLock")
963     final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
964     /**
965      * The sequence number of the last change to a package.
966      * mapping from user id -> package name -> sequence number
967      */
968     @GuardedBy("mLock")
969     final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
970 
971     @GuardedBy("mLock")
972     final private ArraySet<PackageListObserver> mPackageListObservers = new ArraySet<>();
973 
974     @GuardedBy("mLock")
975     private final SparseIntArray mDefaultPermissionsGrantedUsers = new SparseIntArray();
976 
977     private final ModuleInfoProvider mModuleInfoProvider;
978 
979     private final ApexManager mApexManager;
980 
981     private final Injector mInjector;
982 
983     private final SystemWrapper mSystemWrapper;
984 
985     /**
986      * The list of all system partitions that may contain packages in ascending order of
987      * specificity (the more generic, the earlier in the list a partition appears).
988      */
989     @VisibleForTesting(visibility = Visibility.PRIVATE)
990     public static final List<ScanPartition> SYSTEM_PARTITIONS = Collections.unmodifiableList(
991             PackagePartitions.getOrderedPartitions(ScanPartition::new));
992 
993     private final List<ScanPartition> mDirsToScanAsSystem;
994 
995     private final OverlayConfig mOverlayConfig;
996 
997     @GuardedBy("itself")
998     final private ArrayList<IPackageChangeObserver> mPackageChangeObservers =
999         new ArrayList<>();
1000 
1001     // Cached parsed flag value. Invalidated on each flag change.
1002     private PerUidReadTimeouts[] mPerUidReadTimeoutsCache;
1003 
1004     private static final PerUidReadTimeouts[] EMPTY_PER_UID_READ_TIMEOUTS_ARRAY = {};
1005 
1006     /**
1007      * Unit tests will instantiate, extend and/or mock to mock dependencies / behaviors.
1008      *
1009      * NOTE: All getters should return the same instance for every call.
1010      */
1011     @VisibleForTesting(visibility = Visibility.PRIVATE)
1012     public static class Injector {
1013 
1014         @VisibleForTesting(visibility = Visibility.PRIVATE)
1015         interface Producer<T> {
1016             /** Produce an instance of type {@link T} */
produce(Injector injector, PackageManagerService packageManager)1017             T produce(Injector injector, PackageManagerService packageManager);
1018         }
1019 
1020         interface ProducerWithArgument<T, R> {
produce(Injector injector, PackageManagerService packageManager, R argument)1021             T produce(Injector injector, PackageManagerService packageManager, R argument);
1022         }
1023 
1024         interface ServiceProducer {
produce(Class<T> c)1025             <T> T produce(Class<T> c);
1026         }
1027 
1028         @VisibleForTesting(visibility = Visibility.PRIVATE)
1029         static class Singleton<T> {
1030             private final Producer<T> mProducer;
1031             private volatile T mInstance = null;
Singleton(Producer<T> producer)1032             Singleton(Producer<T> producer) {
1033                 this.mProducer = producer;
1034             }
get(Injector injector, PackageManagerService packageManagerService)1035             T get(Injector injector, PackageManagerService packageManagerService) {
1036                 if (mInstance == null) {
1037                     mInstance = mProducer.produce(injector, packageManagerService);
1038                 }
1039                 return mInstance;
1040             }
1041         }
1042 
1043         private PackageManagerService mPackageManager;
1044 
1045         private final PackageAbiHelper mAbiHelper;
1046         private final Context mContext;
1047         private final PackageManagerTracedLock mLock;
1048         private final Installer mInstaller;
1049         private final Object mInstallLock;
1050         private final Handler mBackgroundHandler;
1051         private final Executor mBackgroundExecutor;
1052         private final List<ScanPartition> mSystemPartitions;
1053 
1054 
1055         // ----- producers -----
1056         private final Singleton<ComponentResolver> mComponentResolverProducer;
1057         private final Singleton<PermissionManagerServiceInternal> mPermissionManagerServiceProducer;
1058         private final Singleton<UserManagerService> mUserManagerProducer;
1059         private final Singleton<Settings> mSettingsProducer;
1060         private final Singleton<AppsFilter> mAppsFilterProducer;
1061         private final Singleton<PlatformCompat> mPlatformCompatProducer;
1062         private final Singleton<SystemConfig> mSystemConfigProducer;
1063         private final Singleton<PackageDexOptimizer> mPackageDexOptimizerProducer;
1064         private final Singleton<DexManager> mDexManagerProducer;
1065         private final Singleton<ArtManagerService> mArtManagerServiceProducer;
1066         private final Singleton<ApexManager> mApexManagerProducer;
1067         private final Singleton<ViewCompiler> mViewCompilerProducer;
1068         private final Singleton<IncrementalManager> mIncrementalManagerProducer;
1069         private final Singleton<DefaultAppProvider> mDefaultAppProviderProducer;
1070         private final Singleton<DisplayMetrics> mDisplayMetricsProducer;
1071         private final Producer<PackageParser2> mScanningCachingPackageParserProducer;
1072         private final Producer<PackageParser2> mScanningPackageParserProducer;
1073         private final Producer<PackageParser2> mPreparingPackageParserProducer;
1074         private final Singleton<PackageInstallerService> mPackageInstallerServiceProducer;
1075         private final ProducerWithArgument<InstantAppResolverConnection, ComponentName>
1076                 mInstantAppResolverConnectionProducer;
1077         private final Singleton<LegacyPermissionManagerInternal>
1078                 mLegacyPermissionManagerInternalProducer;
1079         private final SystemWrapper mSystemWrapper;
1080         private final ServiceProducer mGetLocalServiceProducer;
1081         private final ServiceProducer mGetSystemServiceProducer;
1082         private final Singleton<ModuleInfoProvider> mModuleInfoProviderProducer;
1083         private final Singleton<DomainVerificationManagerInternal>
1084                 mDomainVerificationManagerInternalProducer;
1085         private final Singleton<Handler> mHandlerProducer;
1086 
Injector(Context context, PackageManagerTracedLock lock, Installer installer, Object installLock, PackageAbiHelper abiHelper, Handler backgroundHandler, List<ScanPartition> systemPartitions, Producer<ComponentResolver> componentResolverProducer, Producer<PermissionManagerServiceInternal> permissionManagerServiceProducer, Producer<UserManagerService> userManagerProducer, Producer<Settings> settingsProducer, Producer<AppsFilter> appsFilterProducer, Producer<PlatformCompat> platformCompatProducer, Producer<SystemConfig> systemConfigProducer, Producer<PackageDexOptimizer> packageDexOptimizerProducer, Producer<DexManager> dexManagerProducer, Producer<ArtManagerService> artManagerServiceProducer, Producer<ApexManager> apexManagerProducer, Producer<ViewCompiler> viewCompilerProducer, Producer<IncrementalManager> incrementalManagerProducer, Producer<DefaultAppProvider> defaultAppProviderProducer, Producer<DisplayMetrics> displayMetricsProducer, Producer<PackageParser2> scanningCachingPackageParserProducer, Producer<PackageParser2> scanningPackageParserProducer, Producer<PackageParser2> preparingPackageParserProducer, Producer<PackageInstallerService> packageInstallerServiceProducer, ProducerWithArgument<InstantAppResolverConnection, ComponentName> instantAppResolverConnectionProducer, Producer<ModuleInfoProvider> moduleInfoProviderProducer, Producer<LegacyPermissionManagerInternal> legacyPermissionManagerInternalProducer, Producer<DomainVerificationManagerInternal> domainVerificationManagerInternalProducer, Producer<Handler> handlerProducer, SystemWrapper systemWrapper, ServiceProducer getLocalServiceProducer, ServiceProducer getSystemServiceProducer)1087         Injector(Context context, PackageManagerTracedLock lock, Installer installer,
1088                 Object installLock, PackageAbiHelper abiHelper,
1089                 Handler backgroundHandler,
1090                 List<ScanPartition> systemPartitions,
1091                 Producer<ComponentResolver> componentResolverProducer,
1092                 Producer<PermissionManagerServiceInternal> permissionManagerServiceProducer,
1093                 Producer<UserManagerService> userManagerProducer,
1094                 Producer<Settings> settingsProducer,
1095                 Producer<AppsFilter> appsFilterProducer,
1096                 Producer<PlatformCompat> platformCompatProducer,
1097                 Producer<SystemConfig> systemConfigProducer,
1098                 Producer<PackageDexOptimizer> packageDexOptimizerProducer,
1099                 Producer<DexManager> dexManagerProducer,
1100                 Producer<ArtManagerService> artManagerServiceProducer,
1101                 Producer<ApexManager> apexManagerProducer,
1102                 Producer<ViewCompiler> viewCompilerProducer,
1103                 Producer<IncrementalManager> incrementalManagerProducer,
1104                 Producer<DefaultAppProvider> defaultAppProviderProducer,
1105                 Producer<DisplayMetrics> displayMetricsProducer,
1106                 Producer<PackageParser2> scanningCachingPackageParserProducer,
1107                 Producer<PackageParser2> scanningPackageParserProducer,
1108                 Producer<PackageParser2> preparingPackageParserProducer,
1109                 Producer<PackageInstallerService> packageInstallerServiceProducer,
1110                 ProducerWithArgument<InstantAppResolverConnection, ComponentName>
1111                         instantAppResolverConnectionProducer,
1112                 Producer<ModuleInfoProvider> moduleInfoProviderProducer,
1113                 Producer<LegacyPermissionManagerInternal> legacyPermissionManagerInternalProducer,
1114                 Producer<DomainVerificationManagerInternal>
1115                         domainVerificationManagerInternalProducer,
1116                 Producer<Handler> handlerProducer,
1117                 SystemWrapper systemWrapper,
1118                 ServiceProducer getLocalServiceProducer,
1119                 ServiceProducer getSystemServiceProducer) {
1120             mContext = context;
1121             mLock = lock;
1122             mInstaller = installer;
1123             mAbiHelper = abiHelper;
1124             mInstallLock = installLock;
1125             mBackgroundHandler = backgroundHandler;
1126             mBackgroundExecutor = new HandlerExecutor(backgroundHandler);
1127             mSystemPartitions = systemPartitions;
1128             mComponentResolverProducer = new Singleton<>(componentResolverProducer);
1129             mPermissionManagerServiceProducer = new Singleton<>(permissionManagerServiceProducer);
1130             mUserManagerProducer = new Singleton<>(userManagerProducer);
1131             mSettingsProducer = new Singleton<>(settingsProducer);
1132             mAppsFilterProducer = new Singleton<>(appsFilterProducer);
1133             mPlatformCompatProducer = new Singleton<>(platformCompatProducer);
1134             mSystemConfigProducer = new Singleton<>(systemConfigProducer);
1135             mPackageDexOptimizerProducer = new Singleton<>(packageDexOptimizerProducer);
1136             mDexManagerProducer = new Singleton<>(dexManagerProducer);
1137             mArtManagerServiceProducer = new Singleton<>(artManagerServiceProducer);
1138             mApexManagerProducer = new Singleton<>(apexManagerProducer);
1139             mViewCompilerProducer = new Singleton<>(viewCompilerProducer);
1140             mIncrementalManagerProducer = new Singleton<>(incrementalManagerProducer);
1141             mDefaultAppProviderProducer = new Singleton<>(defaultAppProviderProducer);
1142             mDisplayMetricsProducer = new Singleton<>(displayMetricsProducer);
1143             mScanningCachingPackageParserProducer = scanningCachingPackageParserProducer;
1144             mScanningPackageParserProducer = scanningPackageParserProducer;
1145             mPreparingPackageParserProducer = preparingPackageParserProducer;
1146             mPackageInstallerServiceProducer = new Singleton<>(packageInstallerServiceProducer);
1147             mInstantAppResolverConnectionProducer = instantAppResolverConnectionProducer;
1148             mModuleInfoProviderProducer = new Singleton<>(moduleInfoProviderProducer);
1149             mLegacyPermissionManagerInternalProducer = new Singleton<>(
1150                     legacyPermissionManagerInternalProducer);
1151             mSystemWrapper = systemWrapper;
1152             mGetLocalServiceProducer = getLocalServiceProducer;
1153             mGetSystemServiceProducer = getSystemServiceProducer;
1154             mDomainVerificationManagerInternalProducer =
1155                     new Singleton<>(domainVerificationManagerInternalProducer);
1156             mHandlerProducer = new Singleton<>(handlerProducer);
1157         }
1158 
1159         /**
1160          * Bootstraps this injector with the {@link PackageManagerService instance to which it
1161          * belongs.
1162          */
bootstrap(PackageManagerService pm)1163         public void bootstrap(PackageManagerService pm) {
1164             this.mPackageManager = pm;
1165         }
1166 
getUserManagerInternal()1167         public UserManagerInternal getUserManagerInternal() {
1168             return getUserManagerService().getInternalForInjectorOnly();
1169         }
1170 
getAbiHelper()1171         public PackageAbiHelper getAbiHelper() {
1172             return mAbiHelper;
1173         }
1174 
getInstallLock()1175         public Object getInstallLock() {
1176             return mInstallLock;
1177         }
1178 
getSystemPartitions()1179         public List<ScanPartition> getSystemPartitions() {
1180             return mSystemPartitions;
1181         }
1182 
getUserManagerService()1183         public UserManagerService getUserManagerService() {
1184             return mUserManagerProducer.get(this, mPackageManager);
1185         }
1186 
getLock()1187         public PackageManagerTracedLock getLock() {
1188             return mLock;
1189         }
1190 
getInstaller()1191         public Installer getInstaller() {
1192             return mInstaller;
1193         }
1194 
getComponentResolver()1195         public ComponentResolver getComponentResolver() {
1196             return mComponentResolverProducer.get(this, mPackageManager);
1197         }
1198 
getPermissionManagerServiceInternal()1199         public PermissionManagerServiceInternal getPermissionManagerServiceInternal() {
1200             return mPermissionManagerServiceProducer.get(this, mPackageManager);
1201         }
1202 
getContext()1203         public Context getContext() {
1204             return mContext;
1205         }
1206 
getSettings()1207         public Settings getSettings() {
1208             return mSettingsProducer.get(this, mPackageManager);
1209         }
1210 
getAppsFilter()1211         public AppsFilter getAppsFilter() {
1212             return mAppsFilterProducer.get(this, mPackageManager);
1213         }
1214 
getCompatibility()1215         public PlatformCompat getCompatibility() {
1216             return mPlatformCompatProducer.get(this, mPackageManager);
1217         }
1218 
getSystemConfig()1219         public SystemConfig getSystemConfig() {
1220             return mSystemConfigProducer.get(this, mPackageManager);
1221         }
1222 
getPackageDexOptimizer()1223         public PackageDexOptimizer getPackageDexOptimizer() {
1224             return mPackageDexOptimizerProducer.get(this, mPackageManager);
1225         }
1226 
getDexManager()1227         public DexManager getDexManager() {
1228             return mDexManagerProducer.get(this, mPackageManager);
1229         }
1230 
getArtManagerService()1231         public ArtManagerService getArtManagerService() {
1232             return mArtManagerServiceProducer.get(this, mPackageManager);
1233         }
1234 
getApexManager()1235         public ApexManager getApexManager() {
1236             return mApexManagerProducer.get(this, mPackageManager);
1237         }
1238 
getViewCompiler()1239         public ViewCompiler getViewCompiler() {
1240             return mViewCompilerProducer.get(this, mPackageManager);
1241         }
1242 
getBackgroundHandler()1243         public Handler getBackgroundHandler() {
1244             return mBackgroundHandler;
1245         }
1246 
getBackgroundExecutor()1247         public Executor getBackgroundExecutor() {
1248             return mBackgroundExecutor;
1249         }
1250 
getDisplayMetrics()1251         public DisplayMetrics getDisplayMetrics() {
1252             return mDisplayMetricsProducer.get(this, mPackageManager);
1253         }
1254 
getLocalService(Class<T> c)1255         public <T> T getLocalService(Class<T> c) {
1256             return mGetLocalServiceProducer.produce(c);
1257         }
1258 
getSystemService(Class<T> c)1259         public <T> T getSystemService(Class<T> c) {
1260             return mGetSystemServiceProducer.produce(c);
1261         }
1262 
getSystemWrapper()1263         public SystemWrapper getSystemWrapper() {
1264             return mSystemWrapper;
1265         }
1266 
getIncrementalManager()1267         public IncrementalManager getIncrementalManager() {
1268             return mIncrementalManagerProducer.get(this, mPackageManager);
1269         }
1270 
getDefaultAppProvider()1271         public DefaultAppProvider getDefaultAppProvider() {
1272             return mDefaultAppProviderProducer.get(this, mPackageManager);
1273         }
1274 
getScanningCachingPackageParser()1275         public PackageParser2 getScanningCachingPackageParser() {
1276             return mScanningCachingPackageParserProducer.produce(this, mPackageManager);
1277         }
getScanningPackageParser()1278         public PackageParser2 getScanningPackageParser() {
1279             return mScanningPackageParserProducer.produce(this, mPackageManager);
1280         }
getPreparingPackageParser()1281         public PackageParser2 getPreparingPackageParser() {
1282             return mPreparingPackageParserProducer.produce(this, mPackageManager);
1283         }
1284 
getPackageInstallerService()1285         public PackageInstallerService getPackageInstallerService() {
1286             return mPackageInstallerServiceProducer.get(this, mPackageManager);
1287         }
1288 
getInstantAppResolverConnection( ComponentName instantAppResolverComponent)1289         public InstantAppResolverConnection getInstantAppResolverConnection(
1290                 ComponentName instantAppResolverComponent) {
1291             return mInstantAppResolverConnectionProducer.produce(
1292                     this, mPackageManager, instantAppResolverComponent);
1293         }
1294 
getModuleInfoProvider()1295         public ModuleInfoProvider getModuleInfoProvider() {
1296             return mModuleInfoProviderProducer.get(this, mPackageManager);
1297         }
1298 
getLegacyPermissionManagerInternal()1299         public LegacyPermissionManagerInternal getLegacyPermissionManagerInternal() {
1300             return mLegacyPermissionManagerInternalProducer.get(this, mPackageManager);
1301         }
1302 
getDomainVerificationManagerInternal()1303         public DomainVerificationManagerInternal getDomainVerificationManagerInternal() {
1304             return mDomainVerificationManagerInternalProducer.get(this, mPackageManager);
1305         }
1306 
getHandler()1307         public Handler getHandler() {
1308             return mHandlerProducer.get(this, mPackageManager);
1309         }
1310     }
1311 
1312     /** Provides an abstraction to static access to system state. */
1313     public interface SystemWrapper {
disablePackageCaches()1314         void disablePackageCaches();
enablePackageCaches()1315         void enablePackageCaches();
1316     }
1317 
1318     private static class DefaultSystemWrapper implements SystemWrapper {
1319 
1320         @Override
disablePackageCaches()1321         public void disablePackageCaches() {
1322             // disable all package caches that shouldn't apply within system server
1323             PackageManager.disableApplicationInfoCache();
1324             PackageManager.disablePackageInfoCache();
1325             ApplicationPackageManager.invalidateGetPackagesForUidCache();
1326             ApplicationPackageManager.disableGetPackagesForUidCache();
1327             ApplicationPackageManager.invalidateHasSystemFeatureCache();
1328 
1329             // Avoid invalidation-thrashing by preventing cache invalidations from causing property
1330             // writes if the cache isn't enabled yet.  We re-enable writes later when we're
1331             // done initializing.
1332             sSnapshotCorked.incrementAndGet();
1333             PackageManager.corkPackageInfoCache();
1334         }
1335 
1336         @Override
enablePackageCaches()1337         public void enablePackageCaches() {
1338             // Uncork cache invalidations and allow clients to cache package information.
1339             int corking = sSnapshotCorked.decrementAndGet();
1340             if (TRACE_SNAPSHOTS && corking == 0) {
1341                 Log.i(TAG, "snapshot: corking returns to 0");
1342             }
1343             PackageManager.uncorkPackageInfoCache();
1344         }
1345     }
1346 
1347     @VisibleForTesting(visibility = Visibility.PRIVATE)
1348     public static class TestParams {
1349         public ApexManager apexManager;
1350         public @Nullable String appPredictionServicePackage;
1351         public ArtManagerService artManagerService;
1352         public @Nullable String configuratorPackage;
1353         public int defParseFlags;
1354         public DefaultAppProvider defaultAppProvider;
1355         public DexManager dexManager;
1356         public List<ScanPartition> dirsToScanAsSystem;
1357         public @Nullable String documenterPackage;
1358         public boolean factoryTest;
1359         public ArrayMap<String, FeatureInfo> availableFeatures;
1360         public Handler handler;
1361         public @Nullable String incidentReportApproverPackage;
1362         public IncrementalManager incrementalManager;
1363         public PackageInstallerService installerService;
1364         public InstantAppRegistry instantAppRegistry;
1365         public InstantAppResolverConnection instantAppResolverConnection;
1366         public ComponentName instantAppResolverSettingsComponent;
1367         public boolean isPreNmr1Upgrade;
1368         public boolean isPreNupgrade;
1369         public boolean isPreQupgrade;
1370         public boolean isUpgrade;
1371         public LegacyPermissionManagerInternal legacyPermissionManagerInternal;
1372         public DisplayMetrics Metrics;
1373         public ModuleInfoProvider moduleInfoProvider;
1374         public MoveCallbacks moveCallbacks;
1375         public boolean onlyCore;
1376         public OverlayConfig overlayConfig;
1377         public PackageDexOptimizer packageDexOptimizer;
1378         public PackageParser2.Callback packageParserCallback;
1379         public PendingPackageBroadcasts pendingPackageBroadcasts;
1380         public PackageManagerInternal pmInternal;
1381         public TestUtilityService testUtilityService;
1382         public ProcessLoggingHandler processLoggingHandler;
1383         public ProtectedPackages protectedPackages;
1384         public @NonNull String requiredInstallerPackage;
1385         public @NonNull String requiredPermissionControllerPackage;
1386         public @NonNull String requiredUninstallerPackage;
1387         public @Nullable String requiredVerifierPackage;
1388         public String[] separateProcesses;
1389         public @NonNull String servicesExtensionPackageName;
1390         public @Nullable String setupWizardPackage;
1391         public @NonNull String sharedSystemSharedLibraryPackageName;
1392         public @Nullable String storageManagerPackage;
1393         public @Nullable String defaultTextClassifierPackage;
1394         public @Nullable String systemTextClassifierPackage;
1395         public @Nullable String overlayConfigSignaturePackage;
1396         public ViewCompiler viewCompiler;
1397         public @Nullable String retailDemoPackage;
1398         public @Nullable String recentsPackage;
1399         public ComponentName resolveComponentName;
1400         public ArrayMap<String, AndroidPackage> packages;
1401         public boolean enableFreeCacheV2;
1402         public int sdkVersion;
1403         public SystemWrapper systemWrapper;
1404         public File appInstallDir;
1405         public File appLib32InstallDir;
1406         public boolean isEngBuild;
1407         public boolean isUserDebugBuild;
1408         public int sdkInt = Build.VERSION.SDK_INT;
1409         public String incrementalVersion = Build.VERSION.INCREMENTAL;
1410     }
1411 
1412     @Watched
1413     private final AppsFilter mAppsFilter;
1414 
1415     final PackageParser2.Callback mPackageParserCallback;
1416 
1417     // Currently known shared libraries.
1418     @Watched
1419     final WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>
1420             mSharedLibraries = new WatchedArrayMap<>();
1421     private final SnapshotCache<WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>>
1422             mSharedLibrariesSnapshot =
1423             new SnapshotCache.Auto<>(mSharedLibraries, mSharedLibraries,
1424                                      "PackageManagerService.mSharedLibraries");
1425     @Watched
1426     final WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>
1427             mStaticLibsByDeclaringPackage = new WatchedArrayMap<>();
1428     private final SnapshotCache<WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>>
1429             mStaticLibsByDeclaringPackageSnapshot =
1430             new SnapshotCache.Auto<>(mStaticLibsByDeclaringPackage, mStaticLibsByDeclaringPackage,
1431                                      "PackageManagerService.mStaticLibsByDeclaringPackage");
1432 
1433     // Mapping from instrumentation class names to info about them.
1434     @Watched
1435     final WatchedArrayMap<ComponentName, ParsedInstrumentation> mInstrumentation =
1436             new WatchedArrayMap<>();
1437     private final SnapshotCache<WatchedArrayMap<ComponentName, ParsedInstrumentation>>
1438             mInstrumentationSnapshot =
1439             new SnapshotCache.Auto<>(mInstrumentation, mInstrumentation,
1440                                      "PackageManagerService.mInstrumentation");
1441 
1442 
1443     // Packages whose data we have transfered into another package, thus
1444     // should no longer exist.
1445     final ArraySet<String> mTransferredPackages = new ArraySet<>();
1446 
1447     // Broadcast actions that are only available to the system.
1448     @GuardedBy("mProtectedBroadcasts")
1449     final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
1450 
1451     /** List of packages waiting for verification. */
1452     final SparseArray<PackageVerificationState> mPendingVerification = new SparseArray<>();
1453 
1454     /** List of packages waiting for rollback to be enabled. */
1455     final SparseArray<VerificationParams> mPendingEnableRollback = new SparseArray<>();
1456 
1457     final PackageInstallerService mInstallerService;
1458 
1459     final ArtManagerService mArtManagerService;
1460 
1461     private final PackageDexOptimizer mPackageDexOptimizer;
1462     // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
1463     // is used by other apps).
1464     private final DexManager mDexManager;
1465 
1466     private final ViewCompiler mViewCompiler;
1467 
1468     private AtomicInteger mNextMoveId = new AtomicInteger();
1469     private final MoveCallbacks mMoveCallbacks;
1470 
1471     // Cache of users who need badging.
1472     private final SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
1473 
1474     /** Token for keys in mPendingVerification. */
1475     private int mPendingVerificationToken = 0;
1476 
1477     /** Token for keys in mPendingEnableRollback. */
1478     private int mPendingEnableRollbackToken = 0;
1479 
1480     @Watched(manual = true)
1481     volatile boolean mSystemReady;
1482     @Watched(manual = true)
1483     private volatile boolean mSafeMode;
1484     volatile boolean mHasSystemUidErrors;
1485     @Watched
1486     private final WatchedSparseBooleanArray mWebInstantAppsDisabled =
1487             new WatchedSparseBooleanArray();
1488 
1489     @Watched(manual = true)
1490     private ApplicationInfo mAndroidApplication;
1491     @Watched(manual = true)
1492     final ActivityInfo mResolveActivity = new ActivityInfo();
1493     final ResolveInfo mResolveInfo = new ResolveInfo();
1494     @Watched(manual = true)
1495     private ComponentName mResolveComponentName;
1496     AndroidPackage mPlatformPackage;
1497     ComponentName mCustomResolverComponentName;
1498 
1499     boolean mResolverReplaced = false;
1500 
1501     @NonNull
1502     private final DomainVerificationManagerInternal mDomainVerificationManager;
1503 
1504     /** The service connection to the ephemeral resolver */
1505     final InstantAppResolverConnection mInstantAppResolverConnection;
1506     /** Component used to show resolver settings for Instant Apps */
1507     final ComponentName mInstantAppResolverSettingsComponent;
1508 
1509     /** Activity used to install instant applications */
1510     @Watched(manual = true)
1511     private ActivityInfo mInstantAppInstallerActivity;
1512     @Watched(manual = true)
1513     private final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
1514 
1515     private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
1516             mNoKillInstallObservers = Collections.synchronizedMap(new HashMap<>());
1517 
1518     // Internal interface for permission manager
1519     private final PermissionManagerServiceInternal mPermissionManager;
1520 
1521     @Watched
1522     private final ComponentResolver mComponentResolver;
1523 
1524     // List of packages names to keep cached, even if they are uninstalled for all users
1525     private List<String> mKeepUninstalledPackages;
1526 
1527     // Cached reference to IDevicePolicyManager.
1528     private IDevicePolicyManager mDevicePolicyManager = null;
1529 
1530     private File mCacheDir;
1531 
1532     private Future<?> mPrepareAppDataFuture;
1533 
1534     private final IncrementalManager mIncrementalManager;
1535 
1536     private final DefaultAppProvider mDefaultAppProvider;
1537 
1538     private final LegacyPermissionManagerInternal mLegacyPermissionManager;
1539 
1540     private final PackageProperty mPackageProperty = new PackageProperty();
1541 
1542     // Set of pending broadcasts for aggregating enable/disable of components.
1543     @VisibleForTesting(visibility = Visibility.PACKAGE)
1544     public static class PendingPackageBroadcasts {
1545         // for each user id, a map of <package name -> components within that package>
1546         final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1547 
PendingPackageBroadcasts()1548         public PendingPackageBroadcasts() {
1549             mUidMap = new SparseArray<>(2);
1550         }
1551 
get(int userId, String packageName)1552         public ArrayList<String> get(int userId, String packageName) {
1553             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1554             return packages.get(packageName);
1555         }
1556 
put(int userId, String packageName, ArrayList<String> components)1557         public void put(int userId, String packageName, ArrayList<String> components) {
1558             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1559             packages.put(packageName, components);
1560         }
1561 
remove(int userId, String packageName)1562         public void remove(int userId, String packageName) {
1563             ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1564             if (packages != null) {
1565                 packages.remove(packageName);
1566             }
1567         }
1568 
remove(int userId)1569         public void remove(int userId) {
1570             mUidMap.remove(userId);
1571         }
1572 
userIdCount()1573         public int userIdCount() {
1574             return mUidMap.size();
1575         }
1576 
userIdAt(int n)1577         public int userIdAt(int n) {
1578             return mUidMap.keyAt(n);
1579         }
1580 
packagesForUserId(int userId)1581         public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1582             return mUidMap.get(userId);
1583         }
1584 
size()1585         public int size() {
1586             // total number of pending broadcast entries across all userIds
1587             int num = 0;
1588             for (int i = 0; i< mUidMap.size(); i++) {
1589                 num += mUidMap.valueAt(i).size();
1590             }
1591             return num;
1592         }
1593 
clear()1594         public void clear() {
1595             mUidMap.clear();
1596         }
1597 
getOrAllocate(int userId)1598         private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1599             ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1600             if (map == null) {
1601                 map = new ArrayMap<>();
1602                 mUidMap.put(userId, map);
1603             }
1604             return map;
1605         }
1606     }
1607     final PendingPackageBroadcasts mPendingBroadcasts;
1608 
1609     static final int SEND_PENDING_BROADCAST = 1;
1610     static final int INIT_COPY = 5;
1611     static final int POST_INSTALL = 9;
1612     static final int WRITE_SETTINGS = 13;
1613     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1614     static final int PACKAGE_VERIFIED = 15;
1615     static final int CHECK_PENDING_VERIFICATION = 16;
1616     // public static final int UNUSED = 17;
1617     // public static final int UNUSED = 18;
1618     static final int WRITE_PACKAGE_LIST = 19;
1619     static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1620     static final int ENABLE_ROLLBACK_STATUS = 21;
1621     static final int ENABLE_ROLLBACK_TIMEOUT = 22;
1622     static final int DEFERRED_NO_KILL_POST_DELETE = 23;
1623     static final int DEFERRED_NO_KILL_INSTALL_OBSERVER = 24;
1624     static final int INTEGRITY_VERIFICATION_COMPLETE = 25;
1625     static final int CHECK_PENDING_INTEGRITY_VERIFICATION = 26;
1626     static final int DOMAIN_VERIFICATION = 27;
1627     static final int SNAPSHOT_UNCORK = 28;
1628 
1629     static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
1630     static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
1631 
1632     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1633 
1634     private static final long BROADCAST_DELAY_DURING_STARTUP = 10 * 1000L; // 10 seconds (in millis)
1635     private static final long BROADCAST_DELAY = 1 * 1000L; // 1 second (in millis)
1636 
1637     // When the service constructor finished plus a delay (used for broadcast delay computation)
1638     private long mServiceStartWithDelay;
1639 
1640     private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1641             2 * 60 * 60 * 1000L; /* two hours */
1642 
1643     final UserManagerService mUserManager;
1644 
1645     // Stores a list of users whose package restrictions file needs to be updated
1646     private ArraySet<Integer> mDirtyUsers = new ArraySet<>();
1647 
1648     // Recordkeeping of restore-after-install operations that are currently in flight
1649     // between the Package Manager and the Backup Manager
1650     static class PostInstallData {
1651         @Nullable
1652         public final InstallArgs args;
1653         @NonNull
1654         public final PackageInstalledInfo res;
1655         @Nullable
1656         public final Runnable mPostInstallRunnable;
1657 
PostInstallData(@ullable InstallArgs args, @NonNull PackageInstalledInfo res, @Nullable Runnable postInstallRunnable)1658         PostInstallData(@Nullable InstallArgs args, @NonNull PackageInstalledInfo res,
1659                 @Nullable Runnable postInstallRunnable) {
1660             this.args = args;
1661             this.res = res;
1662             mPostInstallRunnable = postInstallRunnable;
1663         }
1664     }
1665 
1666     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<>();
1667     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1668 
1669     // XML tags for backup/restore of various bits of state
1670     private static final String TAG_PREFERRED_BACKUP = "pa";
1671     private static final String TAG_DEFAULT_APPS = "da";
1672     private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1673 
1674     private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1675     private static final String TAG_ALL_GRANTS = "rt-grants";
1676     private static final String TAG_GRANT = "grant";
1677     private static final String ATTR_PACKAGE_NAME = "pkg";
1678 
1679     private static final String TAG_PERMISSION = "perm";
1680     private static final String ATTR_PERMISSION_NAME = "name";
1681     private static final String ATTR_IS_GRANTED = "g";
1682     private static final String ATTR_USER_SET = "set";
1683     private static final String ATTR_USER_FIXED = "fixed";
1684     private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1685 
1686     // System/policy permission grants are not backed up
1687     private static final int SYSTEM_RUNTIME_GRANT_MASK =
1688             FLAG_PERMISSION_POLICY_FIXED
1689             | FLAG_PERMISSION_SYSTEM_FIXED
1690             | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1691 
1692     // And we back up these user-adjusted states
1693     private static final int USER_RUNTIME_GRANT_MASK =
1694             FLAG_PERMISSION_USER_SET
1695             | FLAG_PERMISSION_USER_FIXED
1696             | FLAG_PERMISSION_REVOKED_COMPAT;
1697 
1698     final @Nullable String mRequiredVerifierPackage;
1699     final @NonNull String mRequiredInstallerPackage;
1700     final @NonNull String mRequiredUninstallerPackage;
1701     final @NonNull String mRequiredPermissionControllerPackage;
1702     final @Nullable String mSetupWizardPackage;
1703     final @Nullable String mStorageManagerPackage;
1704     final @Nullable String mDefaultTextClassifierPackage;
1705     final @Nullable String mSystemTextClassifierPackageName;
1706     final @Nullable String mDocumenterPackage;
1707     final @Nullable String mConfiguratorPackage;
1708     final @Nullable String mAppPredictionServicePackage;
1709     final @Nullable String mIncidentReportApproverPackage;
1710     final @Nullable String mServicesExtensionPackageName;
1711     final @Nullable String mSharedSystemSharedLibraryPackageName;
1712     final @Nullable String mRetailDemoPackage;
1713     final @Nullable String mOverlayConfigSignaturePackage;
1714     final @Nullable String mRecentsPackage;
1715 
1716     @GuardedBy("mLock")
1717     private final PackageUsage mPackageUsage = new PackageUsage();
1718     private final CompilerStats mCompilerStats = new CompilerStats();
1719 
1720     private final DomainVerificationConnection mDomainVerificationConnection =
1721             new DomainVerificationConnection();
1722 
1723     private class DomainVerificationConnection implements DomainVerificationService.Connection,
1724             DomainVerificationProxyV1.Connection, DomainVerificationProxyV2.Connection {
1725 
1726         @Override
scheduleWriteSettings()1727         public void scheduleWriteSettings() {
1728             synchronized (mLock) {
1729                 PackageManagerService.this.scheduleWriteSettingsLocked();
1730             }
1731         }
1732 
1733         @Override
getCallingUid()1734         public int getCallingUid() {
1735             return Binder.getCallingUid();
1736         }
1737 
1738         @UserIdInt
1739         @Override
getCallingUserId()1740         public int getCallingUserId() {
1741             return UserHandle.getCallingUserId();
1742         }
1743 
1744         @Override
schedule(int code, @Nullable Object object)1745         public void schedule(int code, @Nullable Object object) {
1746             Message message = mHandler.obtainMessage(DOMAIN_VERIFICATION);
1747             message.arg1 = code;
1748             message.obj = object;
1749             mHandler.sendMessage(message);
1750         }
1751 
1752         @Override
getPowerSaveTempWhitelistAppDuration()1753         public long getPowerSaveTempWhitelistAppDuration() {
1754             return PackageManagerService.this.getVerificationTimeout();
1755         }
1756 
1757         @Override
getDeviceIdleInternal()1758         public DeviceIdleInternal getDeviceIdleInternal() {
1759             return mInjector.getLocalService(DeviceIdleInternal.class);
1760         }
1761 
1762         @Override
isCallerPackage(int callingUid, @NonNull String packageName)1763         public boolean isCallerPackage(int callingUid, @NonNull String packageName) {
1764             final int callingUserId = UserHandle.getUserId(callingUid);
1765             return callingUid == getPackageUid(packageName, 0, callingUserId);
1766         }
1767 
1768         @Nullable
1769         @Override
getPackage(@onNull String packageName)1770         public AndroidPackage getPackage(@NonNull String packageName) {
1771             return PackageManagerService.this.getPackage(packageName);
1772         }
1773 
1774         @Override
filterAppAccess(String packageName, int callingUid, int userId)1775         public boolean filterAppAccess(String packageName, int callingUid, int userId) {
1776             return mPmInternal.filterAppAccess(packageName, callingUid, userId);
1777         }
1778 
1779         @Override
getAllUserIds()1780         public int[] getAllUserIds() {
1781             return mUserManager.getUserIds();
1782         }
1783 
1784         @Override
doesUserExist(@serIdInt int userId)1785         public boolean doesUserExist(@UserIdInt int userId) {
1786             return mUserManager.exists(userId);
1787         }
1788 
1789         @Override
withPackageSettingsSnapshot( @onNull Consumer<Function<String, PackageSetting>> block)1790         public void withPackageSettingsSnapshot(
1791                 @NonNull Consumer<Function<String, PackageSetting>> block) {
1792             mPmInternal.withPackageSettingsSnapshot(block);
1793         }
1794 
1795         @Override
withPackageSettingsSnapshotReturning( @onNull FunctionalUtils.ThrowingFunction<Function<String, PackageSetting>, Output> block)1796         public <Output> Output withPackageSettingsSnapshotReturning(
1797                 @NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageSetting>, Output>
1798                         block) {
1799             return mPmInternal.withPackageSettingsSnapshotReturning(block);
1800         }
1801 
1802         @Override
withPackageSettingsSnapshotThrowing( @onNull FunctionalUtils.ThrowingCheckedConsumer<Function<String, PackageSetting>, ExceptionType> block)1803         public <ExceptionType extends Exception> void withPackageSettingsSnapshotThrowing(
1804                 @NonNull FunctionalUtils.ThrowingCheckedConsumer<Function<String, PackageSetting>,
1805                         ExceptionType> block) throws ExceptionType {
1806             mPmInternal.withPackageSettingsSnapshotThrowing(block);
1807         }
1808 
1809         @Override
1810         public <ExceptionOne extends Exception, ExceptionTwo extends Exception> void
withPackageSettingsSnapshotThrowing2( @onNull FunctionalUtils.ThrowingChecked2Consumer< Function<String, PackageSetting>, ExceptionOne, ExceptionTwo> block)1811                 withPackageSettingsSnapshotThrowing2(
1812                         @NonNull FunctionalUtils.ThrowingChecked2Consumer<
1813                                 Function<String, PackageSetting>, ExceptionOne, ExceptionTwo> block)
1814                 throws ExceptionOne, ExceptionTwo {
1815             mPmInternal.withPackageSettingsSnapshotThrowing2(block);
1816         }
1817 
1818         @Override
1819         public <Output, ExceptionType extends Exception> Output
withPackageSettingsSnapshotReturningThrowing( @onNull FunctionalUtils.ThrowingCheckedFunction< Function<String, PackageSetting>, Output, ExceptionType> block)1820                 withPackageSettingsSnapshotReturningThrowing(
1821                         @NonNull FunctionalUtils.ThrowingCheckedFunction<
1822                                 Function<String, PackageSetting>, Output, ExceptionType> block)
1823                 throws ExceptionType {
1824             return mPmInternal.withPackageSettingsSnapshotReturningThrowing(block);
1825         }
1826     }
1827 
1828     /**
1829      * Invalidate the package info cache, which includes updating the cached computer.
1830      * @hide
1831      */
invalidatePackageInfoCache()1832     public static void invalidatePackageInfoCache() {
1833         PackageManager.invalidatePackageInfoCache();
1834         onChanged();
1835     }
1836 
1837     private final Watcher mWatcher = new Watcher() {
1838             @Override
1839                        public void onChange(@Nullable Watchable what) {
1840                 PackageManagerService.this.onChange(what);
1841             }
1842         };
1843 
1844     /**
1845      * A Snapshot is a subset of PackageManagerService state.  A snapshot is either live
1846      * or snapped.  Live snapshots directly reference PackageManagerService attributes.
1847      * Snapped snapshots contain deep copies of the attributes.
1848      */
1849     private class Snapshot {
1850         public static final int LIVE = 1;
1851         public static final int SNAPPED = 2;
1852 
1853         public final Settings settings;
1854         public final WatchedSparseIntArray isolatedOwners;
1855         public final WatchedArrayMap<String, AndroidPackage> packages;
1856         public final WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>> sharedLibs;
1857         public final WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>> staticLibs;
1858         public final WatchedArrayMap<ComponentName, ParsedInstrumentation> instrumentation;
1859         public final WatchedSparseBooleanArray webInstantAppsDisabled;
1860         public final ComponentName resolveComponentName;
1861         public final ActivityInfo resolveActivity;
1862         public final ActivityInfo instantAppInstallerActivity;
1863         public final ResolveInfo instantAppInstallerInfo;
1864         public final InstantAppRegistry instantAppRegistry;
1865         public final ApplicationInfo androidApplication;
1866         public final String appPredictionServicePackage;
1867         public final AppsFilter appsFilter;
1868         public final ComponentResolver componentResolver;
1869         public final PackageManagerService service;
1870 
Snapshot(int type)1871         Snapshot(int type) {
1872             if (type == Snapshot.SNAPPED) {
1873                 settings = mSettings.snapshot();
1874                 isolatedOwners = mIsolatedOwnersSnapshot.snapshot();
1875                 packages = mPackagesSnapshot.snapshot();
1876                 sharedLibs = mSharedLibrariesSnapshot.snapshot();
1877                 staticLibs = mStaticLibsByDeclaringPackageSnapshot.snapshot();
1878                 instrumentation = mInstrumentationSnapshot.snapshot();
1879                 resolveComponentName = mResolveComponentName.clone();
1880                 resolveActivity = new ActivityInfo(mResolveActivity);
1881                 instantAppInstallerActivity =
1882                         (mInstantAppInstallerActivity == null)
1883                         ? null
1884                         : new ActivityInfo(mInstantAppInstallerActivity);
1885                 instantAppInstallerInfo = new ResolveInfo(mInstantAppInstallerInfo);
1886                 webInstantAppsDisabled = mWebInstantAppsDisabled.snapshot();
1887                 instantAppRegistry = mInstantAppRegistry.snapshot();
1888                 androidApplication =
1889                         (mAndroidApplication == null)
1890                         ? null
1891                         : new ApplicationInfo(mAndroidApplication);
1892                 appPredictionServicePackage = mAppPredictionServicePackage;
1893                 appsFilter = mAppsFilter.snapshot();
1894                 componentResolver = mComponentResolver.snapshot();
1895             } else if (type == Snapshot.LIVE) {
1896                 settings = mSettings;
1897                 isolatedOwners = mIsolatedOwners;
1898                 packages = mPackages;
1899                 sharedLibs = mSharedLibraries;
1900                 staticLibs = mStaticLibsByDeclaringPackage;
1901                 instrumentation = mInstrumentation;
1902                 resolveComponentName = mResolveComponentName;
1903                 resolveActivity = mResolveActivity;
1904                 instantAppInstallerActivity = mInstantAppInstallerActivity;
1905                 instantAppInstallerInfo = mInstantAppInstallerInfo;
1906                 webInstantAppsDisabled = mWebInstantAppsDisabled;
1907                 instantAppRegistry = mInstantAppRegistry;
1908                 androidApplication = mAndroidApplication;
1909                 appPredictionServicePackage = mAppPredictionServicePackage;
1910                 appsFilter = mAppsFilter;
1911                 componentResolver = mComponentResolver;
1912             } else {
1913                 throw new IllegalArgumentException();
1914             }
1915             service = PackageManagerService.this;
1916         }
1917     }
1918 
1919     /**
1920      * A {@link Computer} provides a set of functions that can operate on live data or snapshot
1921      * data.  At this time, the {@link Computer} is implemented by the
1922      * {@link ComputerEngine}, which is in turn extended by {@link ComputerLocked}.
1923      *
1924      * New functions must be added carefully.
1925      * <ol>
1926      * <li> New functions must be true functions with respect to data collected in a
1927      * {@link Snapshot}.  Such data may never be modified from inside a {@link Computer}
1928      * function.
1929      * </li>
1930      *
1931      * <li> A new function must be implemented in {@link ComputerEngine}.
1932      * </li>
1933      *
1934      * <li> A new function must be overridden in {@link ComputerLocked} if the function
1935      * cannot safely access live data without holding the PackageManagerService lock.  The
1936      * form of the {@link ComputerLocked} function must be a single call to the
1937      * {@link ComputerEngine} implementation, wrapped in a <code>synchronized</code>
1938      * block.  Functions in {@link ComputerLocked} should never include any other code.
1939      * </li>
1940      *
1941      * Care must be taken when deciding if a function should be overridden in
1942      * {@link ComputerLocked}.  The complex lock relationships of PackageManagerService
1943      * and other managers (like PermissionManager) mean deadlock is possible.  On the
1944      * other hand, not overriding in {@link ComputerLocked} may leave a function walking
1945      * unstable data.
1946      *
1947      * To coax developers to consider such issues carefully, all methods in
1948      * {@link Computer} must be annotated with <code>@LiveImplementation(override =
1949      * MANDATORY)</code> or <code>LiveImplementation(locked = NOT_ALLOWED)</code>.  A unit
1950      * test verifies the annotation and that the annotation corresponds to the code in
1951      * {@link ComputerEngine} and {@link ComputerLocked}.
1952      */
1953     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
1954     protected interface Computer {
1955 
1956         /**
1957          * Every method must be annotated.
1958          */
1959         @Target({ ElementType.METHOD })
1960         @Retention(RetentionPolicy.RUNTIME)
1961         public @interface LiveImplementation {
1962             // A Computer method must be annotated with one of the following values:
1963             //   MANDATORY - the method must be overridden in ComputerEngineLive.  The
1964             //     format of the override is a call to the super method, wrapped in a
1965             //     synchronization block.
1966             //   NOT_ALLOWED - the method may not appear in the live computer.  It must
1967             //     be final in the ComputerEngine.
1968             int MANDATORY = 1;
1969             int NOT_ALLOWED = 2;
override()1970             int override() default MANDATORY;
rationale()1971             String rationale() default "";
1972         }
1973 
1974         /**
1975          * Administrative statistics: record that the snapshot has been used.  Every call
1976          * to use() increments the usage counter.
1977          */
1978         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
use()1979         default void use() {
1980         }
1981 
1982         /**
1983          * Fetch the snapshot usage counter.
1984          * @return The number of times this snapshot was used.
1985          */
1986         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getUsed()1987         default int getUsed() {
1988             return 0;
1989         }
1990 
1991         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits)1992         @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType,
1993                 int flags, @PrivateResolveFlags int privateResolveFlags, int filterCallingUid,
1994                 int userId, boolean resolveForStart, boolean allowDynamicSplits);
1995         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, int userId)1996         @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType,
1997                 int flags, int userId);
1998         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
queryIntentServicesInternal(Intent intent, String resolvedType, int flags, int userId, int callingUid, boolean includeInstantApps)1999         @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, String resolvedType,
2000                 int flags, int userId, int callingUid, boolean includeInstantApps);
2001         @LiveImplementation(override = LiveImplementation.MANDATORY)
queryIntentActivitiesInternalBody(Intent intent, String resolvedType, int flags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits, String pkgName, String instantAppPkgName)2002         @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(Intent intent,
2003                 String resolvedType, int flags, int filterCallingUid, int userId,
2004                 boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
2005                 String instantAppPkgName);
2006         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getActivityInfo(ComponentName component, int flags, int userId)2007         ActivityInfo getActivityInfo(ComponentName component, int flags, int userId);
2008         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getActivityInfoInternal(ComponentName component, int flags, int filterCallingUid, int userId)2009         ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
2010                 int filterCallingUid, int userId);
2011         @LiveImplementation(override = LiveImplementation.MANDATORY)
getPackage(String packageName)2012         AndroidPackage getPackage(String packageName);
2013         @LiveImplementation(override = LiveImplementation.MANDATORY)
getPackage(int uid)2014         AndroidPackage getPackage(int uid);
2015         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
generateApplicationInfoFromSettingsLPw(String packageName, int flags, int filterCallingUid, int userId)2016         ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
2017                 int filterCallingUid, int userId);
2018         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getApplicationInfo(String packageName, int flags, int userId)2019         ApplicationInfo getApplicationInfo(String packageName, int flags, int userId);
2020         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getApplicationInfoInternal(String packageName, int flags, int filterCallingUid, int userId)2021         ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
2022                 int filterCallingUid, int userId);
2023         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getDefaultHomeActivity(int userId)2024         ComponentName getDefaultHomeActivity(int userId);
2025         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId)2026         ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId);
2027         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType, int flags, int sourceUserId, int parentUserId)2028         CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType,
2029                 int flags, int sourceUserId, int parentUserId);
2030         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getHomeIntent()2031         Intent getHomeIntent();
2032         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getMatchingCrossProfileIntentFilters(Intent intent, String resolvedType, int userId)2033         List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
2034                 String resolvedType, int userId);
2035         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
applyPostResolutionFilter(@onNull List<ResolveInfo> resolveInfos, String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, boolean resolveForStart, int userId, Intent intent)2036         List<ResolveInfo> applyPostResolutionFilter(@NonNull List<ResolveInfo> resolveInfos,
2037                 String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
2038                 boolean resolveForStart, int userId, Intent intent);
2039         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
generatePackageInfo(PackageSetting ps, int flags, int userId)2040         PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId);
2041         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getPackageInfo(String packageName, int flags, int userId)2042         PackageInfo getPackageInfo(String packageName, int flags, int userId);
2043         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getPackageInfoInternal(String packageName, long versionCode, int flags, int filterCallingUid, int userId)2044         PackageInfo getPackageInfoInternal(String packageName, long versionCode, int flags,
2045                 int filterCallingUid, int userId);
2046         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getPackageSetting(String packageName)2047         PackageSetting getPackageSetting(String packageName);
2048         @LiveImplementation(override = LiveImplementation.MANDATORY)
getPackageSettingInternal(String packageName, int callingUid)2049         PackageSetting getPackageSettingInternal(String packageName, int callingUid);
2050         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getInstalledPackages(int flags, int userId)2051         ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId);
2052         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
createForwardingResolveInfoUnchecked(WatchedIntentFilter filter, int sourceUserId, int targetUserId)2053         ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
2054                 int sourceUserId, int targetUserId);
2055         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getServiceInfo(ComponentName component, int flags, int userId)2056         ServiceInfo getServiceInfo(ComponentName component, int flags, int userId);
2057         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getSharedLibraryInfoLPr(String name, long version)2058         SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version);
2059         @LiveImplementation(override = LiveImplementation.MANDATORY)
getInstantAppPackageName(int callingUid)2060         String getInstantAppPackageName(int callingUid);
2061         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
resolveExternalPackageNameLPr(AndroidPackage pkg)2062         String resolveExternalPackageNameLPr(AndroidPackage pkg);
2063         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
resolveInternalPackageNameLPr(String packageName, long versionCode)2064         String resolveInternalPackageNameLPr(String packageName, long versionCode);
2065         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getPackagesForUid(int uid)2066         String[] getPackagesForUid(int uid);
2067         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
getProfileParent(int userId)2068         UserInfo getProfileParent(int userId);
2069         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
canViewInstantApps(int callingUid, int userId)2070         boolean canViewInstantApps(int callingUid, int userId);
2071         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
filterSharedLibPackageLPr(@ullable PackageSetting ps, int uid, int userId, int flags)2072         boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
2073                 int flags);
2074         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
isCallerSameApp(String packageName, int uid)2075         boolean isCallerSameApp(String packageName, int uid);
2076         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
isComponentVisibleToInstantApp(@ullable ComponentName component)2077         boolean isComponentVisibleToInstantApp(@Nullable ComponentName component);
2078         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
isComponentVisibleToInstantApp(@ullable ComponentName component, @ComponentType int type)2079         boolean isComponentVisibleToInstantApp(@Nullable ComponentName component,
2080                 @ComponentType int type);
2081         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId, String resolvedType, int flags)2082         boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId,
2083                 String resolvedType, int flags);
2084         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
isInstantApp(String packageName, int userId)2085         boolean isInstantApp(String packageName, int userId);
2086         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid)2087         boolean isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid);
2088         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
isSameProfileGroup(@serIdInt int callerUserId, @UserIdInt int userId)2089         boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId);
2090         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
shouldFilterApplicationLocked(@ullable PackageSetting ps, int callingUid, @Nullable ComponentName component, @ComponentType int componentType, int userId)2091         boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid,
2092                 @Nullable ComponentName component, @ComponentType int componentType, int userId);
2093         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
shouldFilterApplicationLocked(@ullable PackageSetting ps, int callingUid, int userId)2094         boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid,
2095                 int userId);
2096         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
shouldFilterApplicationLocked(@onNull SharedUserSetting sus, int callingUid, int userId)2097         boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus, int callingUid,
2098                 int userId);
2099         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
checkUidPermission(String permName, int uid)2100         int checkUidPermission(String permName, int uid);
2101         @LiveImplementation(override = LiveImplementation.MANDATORY)
getPackageUidInternal(String packageName, int flags, int userId, int callingUid)2102         int getPackageUidInternal(String packageName, int flags, int userId, int callingUid);
2103         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
updateFlagsForApplication(int flags, int userId)2104         int updateFlagsForApplication(int flags, int userId);
2105         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
updateFlagsForComponent(int flags, int userId)2106         int updateFlagsForComponent(int flags, int userId);
2107         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
updateFlagsForPackage(int flags, int userId)2108         int updateFlagsForPackage(int flags, int userId);
2109         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc)2110         int updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps,
2111                 boolean isImplicitImageCaptureIntentAndNotSetByDpc);
2112         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc)2113         int updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps,
2114                 boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc);
2115         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message)2116         void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
2117                 boolean requireFullPermission, boolean checkShell, String message);
2118         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message)2119         void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
2120                 boolean requireFullPermission, boolean checkShell, String message);
2121         @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, String message)2122         void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
2123                 boolean requireFullPermission, boolean checkShell,
2124                 boolean requirePermissionWhenSameUser, String message);
2125         @LiveImplementation(override = LiveImplementation.MANDATORY)
getSigningDetails(@onNull String packageName)2126         SigningDetails getSigningDetails(@NonNull String packageName);
2127         @LiveImplementation(override = LiveImplementation.MANDATORY)
getSigningDetails(int uid)2128         SigningDetails getSigningDetails(int uid);
2129         @LiveImplementation(override = LiveImplementation.MANDATORY)
filterAppAccess(AndroidPackage pkg, int callingUid, int userId)2130         boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId);
2131         @LiveImplementation(override = LiveImplementation.MANDATORY)
filterAppAccess(String packageName, int callingUid, int userId)2132         boolean filterAppAccess(String packageName, int callingUid, int userId);
2133         @LiveImplementation(override = LiveImplementation.MANDATORY)
dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState)2134         void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState);
2135     }
2136 
2137     /**
2138      * This class contains the implementation of the Computer functions.  It
2139      * is entirely self-contained - it has no implicit access to
2140      * PackageManagerService.
2141      */
2142     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
2143     protected static class ComputerEngine implements Computer {
2144 
2145         // The administrative use counter.
2146         private int mUsed = 0;
2147 
2148         // Cached attributes.  The names in this class are the same as the
2149         // names in PackageManagerService; see that class for documentation.
2150         protected final Settings mSettings;
2151         private final WatchedSparseIntArray mIsolatedOwners;
2152         private final WatchedArrayMap<String, AndroidPackage> mPackages;
2153         private final WatchedArrayMap<ComponentName, ParsedInstrumentation>
2154                 mInstrumentation;
2155         private final WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>
2156                 mStaticLibsByDeclaringPackage;
2157         private final WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>
2158                 mSharedLibraries;
2159         private final ComponentName mLocalResolveComponentName;
2160         private final ActivityInfo mResolveActivity;
2161         private final WatchedSparseBooleanArray mWebInstantAppsDisabled;
2162         private final ActivityInfo mLocalInstantAppInstallerActivity;
2163         private final ResolveInfo mInstantAppInstallerInfo;
2164         private final InstantAppRegistry mInstantAppRegistry;
2165         private final ApplicationInfo mLocalAndroidApplication;
2166         private final AppsFilter mAppsFilter;
2167 
2168         // Immutable service attribute
2169         private final String mAppPredictionServicePackage;
2170 
2171         // The following are not cloned since changes to these have never
2172         // been guarded by the PMS lock.
2173         private final Context mContext;
2174         private final UserManagerService mUserManager;
2175         private final PermissionManagerServiceInternal mPermissionManager;
2176         private final ApexManager mApexManager;
2177         private final Injector mInjector;
2178         private final ComponentResolver mComponentResolver;
2179         private final InstantAppResolverConnection mInstantAppResolverConnection;
2180         private final DefaultAppProvider mDefaultAppProvider;
2181         private final DomainVerificationManagerInternal mDomainVerificationManager;
2182         private final PackageDexOptimizer mPackageDexOptimizer;
2183         private final DexManager mDexManager;
2184         private final CompilerStats mCompilerStats;
2185 
2186         // PackageManagerService attributes that are primitives are referenced through the
2187         // pms object directly.  Primitives are the only attributes so referenced.
2188         protected final PackageManagerService mService;
safeMode()2189         private boolean safeMode() {
2190             return mService.mSafeMode;
2191         }
resolveComponentName()2192         protected ComponentName resolveComponentName() {
2193             return mLocalResolveComponentName;
2194         }
instantAppInstallerActivity()2195         protected ActivityInfo instantAppInstallerActivity() {
2196             return mLocalInstantAppInstallerActivity;
2197         }
androidApplication()2198         protected ApplicationInfo androidApplication() {
2199             return mLocalAndroidApplication;
2200         }
2201 
ComputerEngine(Snapshot args)2202         ComputerEngine(Snapshot args) {
2203             mSettings = args.settings;
2204             mIsolatedOwners = args.isolatedOwners;
2205             mPackages = args.packages;
2206             mSharedLibraries = args.sharedLibs;
2207             mStaticLibsByDeclaringPackage = args.staticLibs;
2208             mInstrumentation = args.instrumentation;
2209             mWebInstantAppsDisabled = args.webInstantAppsDisabled;
2210             mLocalResolveComponentName = args.resolveComponentName;
2211             mResolveActivity = args.resolveActivity;
2212             mLocalInstantAppInstallerActivity = args.instantAppInstallerActivity;
2213             mInstantAppInstallerInfo = args.instantAppInstallerInfo;
2214             mInstantAppRegistry = args.instantAppRegistry;
2215             mLocalAndroidApplication = args.androidApplication;
2216             mAppsFilter = args.appsFilter;
2217             mComponentResolver = args.componentResolver;
2218 
2219             mAppPredictionServicePackage = args.appPredictionServicePackage;
2220 
2221             // The following are not cached copies.  Instead they are
2222             // references to outside services.
2223             mPermissionManager = args.service.mPermissionManager;
2224             mUserManager = args.service.mUserManager;
2225             mContext = args.service.mContext;
2226             mInjector = args.service.mInjector;
2227             mApexManager = args.service.mApexManager;
2228             mInstantAppResolverConnection = args.service.mInstantAppResolverConnection;
2229             mDefaultAppProvider = args.service.mDefaultAppProvider;
2230             mDomainVerificationManager = args.service.mDomainVerificationManager;
2231             mPackageDexOptimizer = args.service.mPackageDexOptimizer;
2232             mDexManager = args.service.mDexManager;
2233             mCompilerStats = args.service.mCompilerStats;
2234 
2235             // Used to reference PMS attributes that are primitives and which are not
2236             // updated under control of the PMS lock.
2237             mService = args.service;
2238         }
2239 
2240         /**
2241          * Record that the snapshot was used.
2242          */
use()2243         public final void use() {
2244             mUsed++;
2245         }
2246 
2247         /**
2248          * Return the usage counter.
2249          */
getUsed()2250         public final int getUsed() {
2251             return mUsed;
2252         }
2253 
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits)2254         public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
2255                 String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags,
2256                 int filterCallingUid, int userId, boolean resolveForStart,
2257                 boolean allowDynamicSplits) {
2258             if (!mUserManager.exists(userId)) return Collections.emptyList();
2259             final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
2260             enforceCrossUserPermission(Binder.getCallingUid(), userId,
2261                     false /* requireFullPermission */, false /* checkShell */,
2262                     "query intent activities");
2263             final String pkgName = intent.getPackage();
2264             ComponentName comp = intent.getComponent();
2265             if (comp == null) {
2266                 if (intent.getSelector() != null) {
2267                     intent = intent.getSelector();
2268                     comp = intent.getComponent();
2269                 }
2270             }
2271 
2272             flags = updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart,
2273                     comp != null || pkgName != null /*onlyExposedExplicitly*/,
2274                     isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
2275                             flags));
2276             if (comp != null) {
2277                 final List<ResolveInfo> list = new ArrayList<>(1);
2278                 final ActivityInfo ai = getActivityInfo(comp, flags, userId);
2279                 if (ai != null) {
2280                     // When specifying an explicit component, we prevent the activity from being
2281                     // used when either 1) the calling package is normal and the activity is within
2282                     // an ephemeral application or 2) the calling package is ephemeral and the
2283                     // activity is not visible to ephemeral applications.
2284                     final boolean matchInstantApp =
2285                             (flags & PackageManager.MATCH_INSTANT) != 0;
2286                     final boolean matchVisibleToInstantAppOnly =
2287                             (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
2288                     final boolean matchExplicitlyVisibleOnly =
2289                             (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
2290                     final boolean isCallerInstantApp =
2291                             instantAppPkgName != null;
2292                     final boolean isTargetSameInstantApp =
2293                             comp.getPackageName().equals(instantAppPkgName);
2294                     final boolean isTargetInstantApp =
2295                             (ai.applicationInfo.privateFlags
2296                                     & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
2297                     final boolean isTargetVisibleToInstantApp =
2298                             (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
2299                     final boolean isTargetExplicitlyVisibleToInstantApp =
2300                             isTargetVisibleToInstantApp
2301                             && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP)
2302                             == 0;
2303                     final boolean isTargetHiddenFromInstantApp =
2304                             !isTargetVisibleToInstantApp
2305                             || (matchExplicitlyVisibleOnly
2306                                     && !isTargetExplicitlyVisibleToInstantApp);
2307                     final boolean blockInstantResolution =
2308                             !isTargetSameInstantApp
2309                             && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
2310                                     || (matchVisibleToInstantAppOnly && isCallerInstantApp
2311                                             && isTargetHiddenFromInstantApp));
2312                     final boolean blockNormalResolution =
2313                             !resolveForStart && !isTargetInstantApp && !isCallerInstantApp
2314                                     && shouldFilterApplicationLocked(
2315                                     getPackageSettingInternal(ai.applicationInfo.packageName,
2316                                             Process.SYSTEM_UID), filterCallingUid, userId);
2317                     if (!blockInstantResolution && !blockNormalResolution) {
2318                         final ResolveInfo ri = new ResolveInfo();
2319                         ri.activityInfo = ai;
2320                         list.add(ri);
2321                     }
2322                 }
2323 
2324                 List<ResolveInfo> result = applyPostResolutionFilter(
2325                         list, instantAppPkgName, allowDynamicSplits, filterCallingUid,
2326                         resolveForStart,
2327                         userId, intent);
2328                 return result;
2329             }
2330 
2331             QueryIntentActivitiesResult lockedResult =
2332                     queryIntentActivitiesInternalBody(
2333                         intent, resolvedType, flags, filterCallingUid, userId, resolveForStart,
2334                         allowDynamicSplits, pkgName, instantAppPkgName);
2335             if (lockedResult.answer != null) {
2336                 return lockedResult.answer;
2337             }
2338 
2339             if (lockedResult.addInstant) {
2340                 String callingPkgName = getInstantAppPackageName(filterCallingUid);
2341                 boolean isRequesterInstantApp = isInstantApp(callingPkgName, userId);
2342                 lockedResult.result = maybeAddInstantAppInstaller(lockedResult.result, intent,
2343                         resolvedType, flags, userId, resolveForStart, isRequesterInstantApp);
2344             }
2345             if (lockedResult.sortResult) {
2346                 Collections.sort(lockedResult.result, RESOLVE_PRIORITY_SORTER);
2347             }
2348             return applyPostResolutionFilter(
2349                     lockedResult.result, instantAppPkgName, allowDynamicSplits, filterCallingUid,
2350                     resolveForStart, userId, intent);
2351         }
2352 
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, int userId)2353         public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
2354                 String resolvedType, int flags, int userId) {
2355             return queryIntentActivitiesInternal(
2356                     intent, resolvedType, flags, 0 /*privateResolveFlags*/, Binder.getCallingUid(),
2357                     userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
2358         }
2359 
queryIntentServicesInternal(Intent intent, String resolvedType, int flags, int userId, int callingUid, boolean includeInstantApps)2360         public final @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
2361                 String resolvedType, int flags, int userId, int callingUid,
2362                 boolean includeInstantApps) {
2363             if (!mUserManager.exists(userId)) return Collections.emptyList();
2364             enforceCrossUserOrProfilePermission(callingUid,
2365                     userId,
2366                     false /*requireFullPermission*/,
2367                     false /*checkShell*/,
2368                     "query intent receivers");
2369             final String instantAppPkgName = getInstantAppPackageName(callingUid);
2370             flags = updateFlagsForResolve(flags, userId, callingUid, includeInstantApps,
2371                     false /* isImplicitImageCaptureIntentAndNotSetByDpc */);
2372             ComponentName comp = intent.getComponent();
2373             if (comp == null) {
2374                 if (intent.getSelector() != null) {
2375                     intent = intent.getSelector();
2376                     comp = intent.getComponent();
2377                 }
2378             }
2379             if (comp != null) {
2380                 final List<ResolveInfo> list = new ArrayList<>(1);
2381                 final ServiceInfo si = getServiceInfo(comp, flags, userId);
2382                 if (si != null) {
2383                     // When specifying an explicit component, we prevent the service from being
2384                     // used when either 1) the service is in an instant application and the
2385                     // caller is not the same instant application or 2) the calling package is
2386                     // ephemeral and the activity is not visible to ephemeral applications.
2387                     final boolean matchInstantApp =
2388                             (flags & PackageManager.MATCH_INSTANT) != 0;
2389                     final boolean matchVisibleToInstantAppOnly =
2390                             (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
2391                     final boolean isCallerInstantApp =
2392                             instantAppPkgName != null;
2393                     final boolean isTargetSameInstantApp =
2394                             comp.getPackageName().equals(instantAppPkgName);
2395                     final boolean isTargetInstantApp =
2396                             (si.applicationInfo.privateFlags
2397                                     & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
2398                     final boolean isTargetHiddenFromInstantApp =
2399                             (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
2400                     final boolean blockInstantResolution =
2401                             !isTargetSameInstantApp
2402                             && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
2403                                     || (matchVisibleToInstantAppOnly && isCallerInstantApp
2404                                             && isTargetHiddenFromInstantApp));
2405 
2406                     final boolean blockNormalResolution = !isTargetInstantApp && !isCallerInstantApp
2407                             && shouldFilterApplicationLocked(
2408                             getPackageSettingInternal(si.applicationInfo.packageName,
2409                                     Process.SYSTEM_UID), callingUid, userId);
2410                     if (!blockInstantResolution && !blockNormalResolution) {
2411                         final ResolveInfo ri = new ResolveInfo();
2412                         ri.serviceInfo = si;
2413                         list.add(ri);
2414                     }
2415                 }
2416                 return list;
2417             }
2418 
2419             return queryIntentServicesInternalBody(intent, resolvedType, flags,
2420                     userId, callingUid, instantAppPkgName);
2421         }
2422 
queryIntentServicesInternalBody(Intent intent, String resolvedType, int flags, int userId, int callingUid, String instantAppPkgName)2423         protected @NonNull List<ResolveInfo> queryIntentServicesInternalBody(Intent intent,
2424                 String resolvedType, int flags, int userId, int callingUid,
2425                 String instantAppPkgName) {
2426             // reader
2427             String pkgName = intent.getPackage();
2428             if (pkgName == null) {
2429                 final List<ResolveInfo> resolveInfos = mComponentResolver.queryServices(intent,
2430                         resolvedType, flags, userId);
2431                 if (resolveInfos == null) {
2432                     return Collections.emptyList();
2433                 }
2434                 return applyPostServiceResolutionFilter(
2435                         resolveInfos, instantAppPkgName, userId, callingUid);
2436             }
2437             final AndroidPackage pkg = mPackages.get(pkgName);
2438             if (pkg != null) {
2439                 final List<ResolveInfo> resolveInfos = mComponentResolver.queryServices(intent,
2440                         resolvedType, flags, pkg.getServices(),
2441                         userId);
2442                 if (resolveInfos == null) {
2443                     return Collections.emptyList();
2444                 }
2445                 return applyPostServiceResolutionFilter(
2446                         resolveInfos, instantAppPkgName, userId, callingUid);
2447             }
2448             return Collections.emptyList();
2449         }
2450 
queryIntentActivitiesInternalBody( Intent intent, String resolvedType, int flags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits, String pkgName, String instantAppPkgName)2451         public @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
2452                 Intent intent, String resolvedType, int flags, int filterCallingUid, int userId,
2453                 boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
2454                 String instantAppPkgName) {
2455             // reader
2456             boolean sortResult = false;
2457             boolean addInstant = false;
2458             List<ResolveInfo> result = null;
2459             if (pkgName == null) {
2460                 List<CrossProfileIntentFilter> matchingFilters =
2461                         getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
2462                 // Check for results that need to skip the current profile.
2463                 ResolveInfo skipProfileInfo  = querySkipCurrentProfileIntents(matchingFilters,
2464                         intent, resolvedType, flags, userId);
2465                 if (skipProfileInfo != null) {
2466                     List<ResolveInfo> xpResult = new ArrayList<>(1);
2467                     xpResult.add(skipProfileInfo);
2468                     return new QueryIntentActivitiesResult(
2469                             applyPostResolutionFilter(
2470                                     filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
2471                                     allowDynamicSplits, filterCallingUid, resolveForStart, userId,
2472                                     intent));
2473                 }
2474 
2475                 // Check for results in the current profile.
2476                 result = filterIfNotSystemUser(mComponentResolver.queryActivities(
2477                         intent, resolvedType, flags, userId), userId);
2478                 addInstant = isInstantAppResolutionAllowed(intent, result, userId,
2479                         false /*skipPackageCheck*/, flags);
2480                 // Check for cross profile results.
2481                 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
2482                 CrossProfileDomainInfo specificXpInfo = queryCrossProfileIntents(
2483                         matchingFilters, intent, resolvedType, flags, userId,
2484                         hasNonNegativePriorityResult);
2485                 if (intent.hasWebURI()) {
2486                     CrossProfileDomainInfo generalXpInfo = null;
2487                     final UserInfo parent = getProfileParent(userId);
2488                     if (parent != null) {
2489                         generalXpInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
2490                                 flags, userId, parent.id);
2491                     }
2492 
2493                     // Generalized cross profile intents take precedence over specific.
2494                     // Note that this is the opposite of the intuitive order.
2495                     CrossProfileDomainInfo prioritizedXpInfo =
2496                             generalXpInfo != null ? generalXpInfo : specificXpInfo;
2497 
2498                     if (!addInstant) {
2499                         if (result.isEmpty() && prioritizedXpInfo != null) {
2500                             // No result in current profile, but found candidate in parent user.
2501                             // And we are not going to add ephemeral app, so we can return the
2502                             // result straight away.
2503                             result.add(prioritizedXpInfo.resolveInfo);
2504                             return new QueryIntentActivitiesResult(
2505                                     applyPostResolutionFilter(result, instantAppPkgName,
2506                                             allowDynamicSplits, filterCallingUid, resolveForStart,
2507                                             userId, intent));
2508                         } else if (result.size() <= 1 && prioritizedXpInfo == null) {
2509                             // No result in parent user and <= 1 result in current profile, and we
2510                             // are not going to add ephemeral app, so we can return the result
2511                             // without further processing.
2512                             return new QueryIntentActivitiesResult(
2513                                     applyPostResolutionFilter(result, instantAppPkgName,
2514                                             allowDynamicSplits, filterCallingUid, resolveForStart,
2515                                             userId, intent));
2516                         }
2517                     }
2518 
2519                     // We have more than one candidate (combining results from current and parent
2520                     // profile), so we need filtering and sorting.
2521                     result = filterCandidatesWithDomainPreferredActivitiesLPr(
2522                             intent, flags, result, prioritizedXpInfo, userId);
2523                     sortResult = true;
2524                 } else {
2525                     // If not web Intent, just add result to candidate set and let ResolverActivity
2526                     // figure it out.
2527                     if (specificXpInfo != null) {
2528                         result.add(specificXpInfo.resolveInfo);
2529                         sortResult = true;
2530                     }
2531                 }
2532             } else {
2533                 final PackageSetting setting =
2534                         getPackageSettingInternal(pkgName, Process.SYSTEM_UID);
2535                 result = null;
2536                 if (setting != null && setting.pkg != null && (resolveForStart
2537                         || !shouldFilterApplicationLocked(setting, filterCallingUid, userId))) {
2538                     result = filterIfNotSystemUser(mComponentResolver.queryActivities(
2539                             intent, resolvedType, flags, setting.pkg.getActivities(), userId),
2540                             userId);
2541                 }
2542                 if (result == null || result.size() == 0) {
2543                     // the caller wants to resolve for a particular package; however, there
2544                     // were no installed results, so, try to find an ephemeral result
2545                     addInstant = isInstantAppResolutionAllowed(intent, null /*result*/, userId,
2546                             true /*skipPackageCheck*/, flags);
2547                     if (result == null) {
2548                         result = new ArrayList<>();
2549                     }
2550                 }
2551             }
2552             return new QueryIntentActivitiesResult(sortResult, addInstant, result);
2553         }
2554 
2555         /**
2556          * Returns the activity component that can handle install failures.
2557          * <p>By default, the instant application installer handles failures. However, an
2558          * application may want to handle failures on its own. Applications do this by
2559          * creating an activity with an intent filter that handles the action
2560          * {@link Intent#ACTION_INSTALL_FAILURE}.
2561          */
findInstallFailureActivity( String packageName, int filterCallingUid, int userId)2562         private @Nullable ComponentName findInstallFailureActivity(
2563                 String packageName, int filterCallingUid, int userId) {
2564             final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
2565             failureActivityIntent.setPackage(packageName);
2566             // IMPORTANT: disallow dynamic splits to avoid an infinite loop
2567             final List<ResolveInfo> result = queryIntentActivitiesInternal(
2568                     failureActivityIntent, null /*resolvedType*/, 0 /*flags*/,
2569                     0 /*privateResolveFlags*/, filterCallingUid, userId, false /*resolveForStart*/,
2570                     false /*allowDynamicSplits*/);
2571             final int NR = result.size();
2572             if (NR > 0) {
2573                 for (int i = 0; i < NR; i++) {
2574                     final ResolveInfo info = result.get(i);
2575                     if (info.activityInfo.splitName != null) {
2576                         continue;
2577                     }
2578                     return new ComponentName(packageName, info.activityInfo.name);
2579                 }
2580             }
2581             return null;
2582         }
2583 
getActivityInfo(ComponentName component, int flags, int userId)2584         public final ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
2585             return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
2586         }
2587 
2588         /**
2589          * Important: The provided filterCallingUid is used exclusively to filter out activities
2590          * that can be seen based on user state. It's typically the original caller uid prior
2591          * to clearing. Because it can only be provided by trusted code, its value can be
2592          * trusted and will be used as-is; unlike userId which will be validated by this method.
2593          */
getActivityInfoInternal(ComponentName component, int flags, int filterCallingUid, int userId)2594         public final ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
2595                 int filterCallingUid, int userId) {
2596             if (!mUserManager.exists(userId)) return null;
2597             flags = updateFlagsForComponent(flags, userId);
2598 
2599             if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
2600                 enforceCrossUserPermission(Binder.getCallingUid(), userId,
2601                         false /* requireFullPermission */, false /* checkShell */,
2602                         "get activity info");
2603             }
2604 
2605             return getActivityInfoInternalBody(component, flags, filterCallingUid, userId);
2606         }
2607 
getActivityInfoInternalBody(ComponentName component, int flags, int filterCallingUid, int userId)2608         protected ActivityInfo getActivityInfoInternalBody(ComponentName component, int flags,
2609                 int filterCallingUid, int userId) {
2610             ParsedActivity a = mComponentResolver.getActivity(component);
2611 
2612             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
2613 
2614             AndroidPackage pkg = a == null ? null : mPackages.get(a.getPackageName());
2615             if (pkg != null && mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) {
2616                 PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
2617                 if (ps == null) return null;
2618                 if (shouldFilterApplicationLocked(
2619                         ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
2620                     return null;
2621                 }
2622                 return PackageInfoUtils.generateActivityInfo(pkg,
2623                         a, flags, ps.readUserState(userId), userId, ps);
2624             }
2625             if (resolveComponentName().equals(component)) {
2626                 return PackageParser.generateActivityInfo(
2627                         mResolveActivity, flags, new PackageUserState(), userId);
2628             }
2629             return null;
2630         }
2631 
getPackage(String packageName)2632         public AndroidPackage getPackage(String packageName) {
2633             packageName = resolveInternalPackageNameLPr(
2634                     packageName, PackageManager.VERSION_CODE_HIGHEST);
2635             return mPackages.get(packageName);
2636         }
2637 
getPackage(int uid)2638         public AndroidPackage getPackage(int uid) {
2639             final String[] packageNames = getPackagesForUidInternal(uid, Process.SYSTEM_UID);
2640             AndroidPackage pkg = null;
2641             final int numPackages = packageNames == null ? 0 : packageNames.length;
2642             for (int i = 0; pkg == null && i < numPackages; i++) {
2643                 pkg = mPackages.get(packageNames[i]);
2644             }
2645             return pkg;
2646         }
2647 
generateApplicationInfoFromSettingsLPw(String packageName, int flags, int filterCallingUid, int userId)2648         public final ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName,
2649                 int flags, int filterCallingUid, int userId) {
2650             if (!mUserManager.exists(userId)) return null;
2651             PackageSetting ps = mSettings.getPackageLPr(packageName);
2652             if (ps != null) {
2653                 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
2654                     return null;
2655                 }
2656                 if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
2657                     return null;
2658                 }
2659                 if (ps.pkg == null) {
2660                     final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
2661                     if (pInfo != null) {
2662                         return pInfo.applicationInfo;
2663                     }
2664                     return null;
2665                 }
2666                 ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(ps.pkg, flags,
2667                         ps.readUserState(userId), userId, ps);
2668                 if (ai != null) {
2669                     ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
2670                 }
2671                 return ai;
2672             }
2673             return null;
2674         }
2675 
getApplicationInfo(String packageName, int flags, int userId)2676         public final ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
2677             return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
2678         }
2679 
2680         /**
2681          * Important: The provided filterCallingUid is used exclusively to filter out applications
2682          * that can be seen based on user state. It's typically the original caller uid prior
2683          * to clearing. Because it can only be provided by trusted code, its value can be
2684          * trusted and will be used as-is; unlike userId which will be validated by this method.
2685          */
getApplicationInfoInternal(String packageName, int flags, int filterCallingUid, int userId)2686         public final ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
2687                 int filterCallingUid, int userId) {
2688             if (!mUserManager.exists(userId)) return null;
2689             flags = updateFlagsForApplication(flags, userId);
2690 
2691             if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
2692                 enforceCrossUserPermission(Binder.getCallingUid(), userId,
2693                         false /* requireFullPermission */, false /* checkShell */,
2694                         "get application info");
2695             }
2696 
2697             return getApplicationInfoInternalBody(packageName, flags, filterCallingUid, userId);
2698         }
2699 
getApplicationInfoInternalBody(String packageName, int flags, int filterCallingUid, int userId)2700         protected ApplicationInfo getApplicationInfoInternalBody(String packageName, int flags,
2701                 int filterCallingUid, int userId) {
2702             // writer
2703             // Normalize package name to handle renamed packages and static libs
2704             packageName = resolveInternalPackageNameLPr(packageName,
2705                     PackageManager.VERSION_CODE_HIGHEST);
2706 
2707             AndroidPackage p = mPackages.get(packageName);
2708             if (DEBUG_PACKAGE_INFO) Log.v(
2709                     TAG, "getApplicationInfo " + packageName
2710                     + ": " + p);
2711             if (p != null) {
2712                 PackageSetting ps = mSettings.getPackageLPr(packageName);
2713                 if (ps == null) return null;
2714                 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
2715                     return null;
2716                 }
2717                 if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
2718                     return null;
2719                 }
2720                 // Note: isEnabledLP() does not apply here - always return info
2721                 ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(
2722                         p, flags, ps.readUserState(userId), userId, ps);
2723                 if (ai != null) {
2724                     ai.packageName = resolveExternalPackageNameLPr(p);
2725                 }
2726                 return ai;
2727             }
2728             if ((flags & PackageManager.MATCH_APEX) != 0) {
2729                 // For APKs, PackageInfo.applicationInfo is not exactly the same as ApplicationInfo
2730                 // returned from getApplicationInfo, but for APEX packages difference shouldn't be
2731                 // very big.
2732                 // TODO(b/155328545): generate proper application info for APEXes as well.
2733                 int apexFlags = ApexManager.MATCH_ACTIVE_PACKAGE;
2734                 if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) {
2735                     apexFlags = ApexManager.MATCH_FACTORY_PACKAGE;
2736                 }
2737                 final PackageInfo pi = mApexManager.getPackageInfo(packageName, apexFlags);
2738                 if (pi == null) {
2739                     return null;
2740                 }
2741                 return pi.applicationInfo;
2742             }
2743             if ("android".equals(packageName)||"system".equals(packageName)) {
2744                 return androidApplication();
2745             }
2746             if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
2747                 // Already generates the external package name
2748                 return generateApplicationInfoFromSettingsLPw(packageName,
2749                         flags, filterCallingUid, userId);
2750             }
2751             return null;
2752         }
2753 
filterCandidatesWithDomainPreferredActivitiesLPrBody( Intent intent, int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, int userId, boolean debug)2754         protected ArrayList<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPrBody(
2755                 Intent intent, int matchFlags, List<ResolveInfo> candidates,
2756                 CrossProfileDomainInfo xpDomainInfo, int userId, boolean debug) {
2757             final ArrayList<ResolveInfo> result = new ArrayList<>();
2758             final ArrayList<ResolveInfo> matchAllList = new ArrayList<>();
2759             final ArrayList<ResolveInfo> undefinedList = new ArrayList<>();
2760 
2761             // Blocking instant apps is usually done in applyPostResolutionFilter, but since
2762             // domain verification can resolve to a single result, which can be an instant app,
2763             // it will then be filtered to an empty list in that method. Instead, do blocking
2764             // here so that instant apps can be ignored for approval filtering and a lower
2765             // priority result chosen instead.
2766             final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled(userId);
2767 
2768             final int count = candidates.size();
2769             // First, try to use approved apps.
2770             for (int n = 0; n < count; n++) {
2771                 ResolveInfo info = candidates.get(n);
2772                 if (blockInstant && (info.isInstantAppAvailable
2773                         || isInstantApp(info.activityInfo.packageName, userId))) {
2774                     continue;
2775                 }
2776 
2777                 // Add to the special match all list (Browser use case)
2778                 if (info.handleAllWebDataURI) {
2779                     matchAllList.add(info);
2780                 } else {
2781                     undefinedList.add(info);
2782                 }
2783             }
2784 
2785             // We'll want to include browser possibilities in a few cases
2786             boolean includeBrowser = false;
2787 
2788             if (!DomainVerificationUtils.isDomainVerificationIntent(intent, matchFlags)) {
2789                 result.addAll(undefinedList);
2790                 // Maybe add one for the other profile.
2791                 if (xpDomainInfo != null && xpDomainInfo.highestApprovalLevel
2792                         > DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE) {
2793                     result.add(xpDomainInfo.resolveInfo);
2794                 }
2795                 includeBrowser = true;
2796             } else {
2797                 Pair<List<ResolveInfo>, Integer> infosAndLevel = mDomainVerificationManager
2798                         .filterToApprovedApp(intent, undefinedList, userId,
2799                                 mSettings::getPackageLPr);
2800                 List<ResolveInfo> approvedInfos = infosAndLevel.first;
2801                 Integer highestApproval = infosAndLevel.second;
2802 
2803                 // If no apps are approved for the domain, resolve only to browsers
2804                 if (approvedInfos.isEmpty()) {
2805                     includeBrowser = true;
2806                     if (xpDomainInfo != null && xpDomainInfo.highestApprovalLevel
2807                             > DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE) {
2808                         result.add(xpDomainInfo.resolveInfo);
2809                     }
2810                 } else {
2811                     result.addAll(approvedInfos);
2812 
2813                     // If the other profile has an app that's higher approval, add it
2814                     if (xpDomainInfo != null
2815                             && xpDomainInfo.highestApprovalLevel > highestApproval) {
2816                         result.add(xpDomainInfo.resolveInfo);
2817                     }
2818                 }
2819             }
2820 
2821             if (includeBrowser) {
2822                 // Also add browsers (all of them or only the default one)
2823                 if (DEBUG_DOMAIN_VERIFICATION) {
2824                     Slog.v(TAG, "   ...including browsers in candidate set");
2825                 }
2826                 if ((matchFlags & MATCH_ALL) != 0) {
2827                     result.addAll(matchAllList);
2828                 } else {
2829                     // Browser/generic handling case.  If there's a default browser, go straight
2830                     // to that (but only if there is no other higher-priority match).
2831                     final String defaultBrowserPackageName = mDefaultAppProvider.getDefaultBrowser(
2832                             userId);
2833                     int maxMatchPrio = 0;
2834                     ResolveInfo defaultBrowserMatch = null;
2835                     final int numCandidates = matchAllList.size();
2836                     for (int n = 0; n < numCandidates; n++) {
2837                         ResolveInfo info = matchAllList.get(n);
2838                         // track the highest overall match priority...
2839                         if (info.priority > maxMatchPrio) {
2840                             maxMatchPrio = info.priority;
2841                         }
2842                         // ...and the highest-priority default browser match
2843                         if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
2844                             if (defaultBrowserMatch == null
2845                                     || (defaultBrowserMatch.priority < info.priority)) {
2846                                 if (debug) {
2847                                     Slog.v(TAG, "Considering default browser match " + info);
2848                                 }
2849                                 defaultBrowserMatch = info;
2850                             }
2851                         }
2852                     }
2853                     if (defaultBrowserMatch != null
2854                             && defaultBrowserMatch.priority >= maxMatchPrio
2855                             && !TextUtils.isEmpty(defaultBrowserPackageName))
2856                     {
2857                         if (debug) {
2858                             Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
2859                         }
2860                         result.add(defaultBrowserMatch);
2861                     } else {
2862                         result.addAll(matchAllList);
2863                     }
2864                 }
2865 
2866                 // If there is nothing selected, add all candidates
2867                 if (result.size() == 0) {
2868                     result.addAll(candidates);
2869                 }
2870             }
2871             return result;
2872         }
2873 
2874         /**
2875          * Report the 'Home' activity which is currently set as "always use this one". If non is set
2876          * then reports the most likely home activity or null if there are more than one.
2877          */
getDefaultHomeActivity(int userId)2878         public final ComponentName getDefaultHomeActivity(int userId) {
2879             List<ResolveInfo> allHomeCandidates = new ArrayList<>();
2880             ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
2881             if (cn != null) {
2882                 return cn;
2883             }
2884             // TODO: This should not happen since there should always be a default package set for
2885             //  ROLE_HOME in RoleManager. Continue with a warning log for now.
2886             Slog.w(TAG, "Default package for ROLE_HOME is not set in RoleManager");
2887 
2888             // Find the launcher with the highest priority and return that component if there are no
2889             // other home activity with the same priority.
2890             int lastPriority = Integer.MIN_VALUE;
2891             ComponentName lastComponent = null;
2892             final int size = allHomeCandidates.size();
2893             for (int i = 0; i < size; i++) {
2894                 final ResolveInfo ri = allHomeCandidates.get(i);
2895                 if (ri.priority > lastPriority) {
2896                     lastComponent = ri.activityInfo.getComponentName();
2897                     lastPriority = ri.priority;
2898                 } else if (ri.priority == lastPriority) {
2899                     // Two components found with same priority.
2900                     lastComponent = null;
2901                 }
2902             }
2903             return lastComponent;
2904         }
2905 
getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId)2906         public final ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
2907                 int userId) {
2908             Intent intent  = getHomeIntent();
2909             List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
2910                     PackageManager.GET_META_DATA, userId);
2911             allHomeCandidates.clear();
2912             if (resolveInfos == null) {
2913                 return null;
2914             }
2915             allHomeCandidates.addAll(resolveInfos);
2916 
2917             final String packageName = mDefaultAppProvider.getDefaultHome(userId);
2918             if (packageName == null) {
2919                 return null;
2920             }
2921 
2922             int resolveInfosSize = resolveInfos.size();
2923             for (int i = 0; i < resolveInfosSize; i++) {
2924                 ResolveInfo resolveInfo = resolveInfos.get(i);
2925 
2926                 if (resolveInfo.activityInfo != null && TextUtils.equals(
2927                         resolveInfo.activityInfo.packageName, packageName)) {
2928                     return new ComponentName(resolveInfo.activityInfo.packageName,
2929                             resolveInfo.activityInfo.name);
2930                 }
2931             }
2932             return null;
2933         }
2934 
getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType, int flags, int sourceUserId, int parentUserId)2935         public final CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
2936                 String resolvedType, int flags, int sourceUserId, int parentUserId) {
2937             if (!mUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
2938                     sourceUserId)) {
2939                 return null;
2940             }
2941             List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent,
2942                     resolvedType, flags, parentUserId);
2943 
2944             if (resultTargetUser == null || resultTargetUser.isEmpty()) {
2945                 return null;
2946             }
2947             CrossProfileDomainInfo result = null;
2948             int size = resultTargetUser.size();
2949             for (int i = 0; i < size; i++) {
2950                 ResolveInfo riTargetUser = resultTargetUser.get(i);
2951                 // Intent filter verification is only for filters that specify a host. So don't
2952                 //return
2953                 // those that handle all web uris.
2954                 if (riTargetUser.handleAllWebDataURI) {
2955                     continue;
2956                 }
2957                 String packageName = riTargetUser.activityInfo.packageName;
2958                 PackageSetting ps = mSettings.getPackageLPr(packageName);
2959                 if (ps == null) {
2960                     continue;
2961                 }
2962 
2963                 int approvalLevel = mDomainVerificationManager
2964                         .approvalLevelForDomain(ps, intent, flags, parentUserId);
2965 
2966                 if (result == null) {
2967                     result = new CrossProfileDomainInfo(createForwardingResolveInfoUnchecked(
2968                             new WatchedIntentFilter(), sourceUserId, parentUserId), approvalLevel);
2969                 } else {
2970                     result.highestApprovalLevel =
2971                             Math.max(approvalLevel, result.highestApprovalLevel);
2972                 }
2973             }
2974             if (result != null && result.highestApprovalLevel
2975                     <= DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE) {
2976                 return null;
2977             }
2978             return result;
2979         }
2980 
getHomeIntent()2981         public final Intent getHomeIntent() {
2982             Intent intent = new Intent(Intent.ACTION_MAIN);
2983             intent.addCategory(Intent.CATEGORY_HOME);
2984             intent.addCategory(Intent.CATEGORY_DEFAULT);
2985             return intent;
2986         }
2987 
getMatchingCrossProfileIntentFilters( Intent intent, String resolvedType, int userId)2988         public final List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(
2989                 Intent intent, String resolvedType, int userId) {
2990             CrossProfileIntentResolver resolver = mSettings.getCrossProfileIntentResolver(userId);
2991             if (resolver != null) {
2992                 return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
2993             }
2994             return null;
2995         }
2996 
2997         /**
2998          * Filters out ephemeral activities.
2999          * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
3000          * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
3001          *
3002          * @param resolveInfos The pre-filtered list of resolved activities
3003          * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
3004          *          is performed.
3005          * @param intent
3006          * @return A filtered list of resolved activities.
3007          */
applyPostResolutionFilter( @onNull List<ResolveInfo> resolveInfos, String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, boolean resolveForStart, int userId, Intent intent)3008         public final List<ResolveInfo> applyPostResolutionFilter(
3009                 @NonNull List<ResolveInfo> resolveInfos,
3010                 String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
3011                 boolean resolveForStart, int userId, Intent intent) {
3012             final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled(userId);
3013             for (int i = resolveInfos.size() - 1; i >= 0; i--) {
3014                 final ResolveInfo info = resolveInfos.get(i);
3015                 // remove locally resolved instant app web results when disabled
3016                 if (info.isInstantAppAvailable && blockInstant) {
3017                     resolveInfos.remove(i);
3018                     continue;
3019                 }
3020                 // allow activities that are defined in the provided package
3021                 if (allowDynamicSplits
3022                         && info.activityInfo != null
3023                         && info.activityInfo.splitName != null
3024                         && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
3025                                 info.activityInfo.splitName)) {
3026                     if (instantAppInstallerActivity() == null) {
3027                         if (DEBUG_INSTALL) {
3028                             Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
3029                         }
3030                         resolveInfos.remove(i);
3031                         continue;
3032                     }
3033                     if (blockInstant && isInstantApp(info.activityInfo.packageName, userId)) {
3034                         resolveInfos.remove(i);
3035                         continue;
3036                     }
3037                     // requested activity is defined in a split that hasn't been installed yet.
3038                     // add the installer to the resolve list
3039                     if (DEBUG_INSTALL) {
3040                         Slog.v(TAG, "Adding installer to the ResolveInfo list");
3041                     }
3042                     final ResolveInfo installerInfo = new ResolveInfo(
3043                             mInstantAppInstallerInfo);
3044                     final ComponentName installFailureActivity = findInstallFailureActivity(
3045                             info.activityInfo.packageName,  filterCallingUid, userId);
3046                     installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
3047                             installFailureActivity,
3048                             info.activityInfo.packageName,
3049                             info.activityInfo.applicationInfo.longVersionCode,
3050                             info.activityInfo.splitName);
3051                     // add a non-generic filter
3052                     installerInfo.filter = new IntentFilter();
3053 
3054                     // This resolve info may appear in the chooser UI, so let us make it
3055                     // look as the one it replaces as far as the user is concerned which
3056                     // requires loading the correct label and icon for the resolve info.
3057                     installerInfo.resolvePackageName = info.getComponentInfo().packageName;
3058                     installerInfo.labelRes = info.resolveLabelResId();
3059                     installerInfo.icon = info.resolveIconResId();
3060                     installerInfo.isInstantAppAvailable = true;
3061                     resolveInfos.set(i, installerInfo);
3062                     continue;
3063                 }
3064                 if (ephemeralPkgName == null) {
3065                     // caller is a full app
3066                     SettingBase callingSetting =
3067                             mSettings.getSettingLPr(UserHandle.getAppId(filterCallingUid));
3068                     PackageSetting resolvedSetting =
3069                             getPackageSettingInternal(info.activityInfo.packageName, 0);
3070                     if (resolveForStart
3071                             || !mAppsFilter.shouldFilterApplication(
3072                                     filterCallingUid, callingSetting, resolvedSetting, userId)) {
3073                         continue;
3074                     }
3075                 } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
3076                     // caller is same app; don't need to apply any other filtering
3077                     continue;
3078                 } else if (resolveForStart
3079                         && (intent.isWebIntent()
3080                                 || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0)
3081                         && intent.getPackage() == null
3082                         && intent.getComponent() == null) {
3083                     // ephemeral apps can launch other ephemeral apps indirectly
3084                     continue;
3085                 } else if (((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP)
3086                                 != 0)
3087                         && !info.activityInfo.applicationInfo.isInstantApp()) {
3088                     // allow activities that have been explicitly exposed to ephemeral apps
3089                     continue;
3090                 }
3091                 resolveInfos.remove(i);
3092             }
3093             return resolveInfos;
3094         }
3095 
applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos, String instantAppPkgName, @UserIdInt int userId, int filterCallingUid)3096         private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
3097                 String instantAppPkgName, @UserIdInt int userId, int filterCallingUid) {
3098             for (int i = resolveInfos.size() - 1; i >= 0; i--) {
3099                 final ResolveInfo info = resolveInfos.get(i);
3100                 if (instantAppPkgName == null) {
3101                     SettingBase callingSetting =
3102                             mSettings.getSettingLPr(UserHandle.getAppId(filterCallingUid));
3103                     PackageSetting resolvedSetting =
3104                             getPackageSettingInternal(info.serviceInfo.packageName, 0);
3105                     if (!mAppsFilter.shouldFilterApplication(
3106                             filterCallingUid, callingSetting, resolvedSetting, userId)) {
3107                         continue;
3108                     }
3109                 }
3110                 final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
3111                 // allow services that are defined in the provided package
3112                 if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
3113                     if (info.serviceInfo.splitName != null
3114                             && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
3115                                     info.serviceInfo.splitName)) {
3116                         if (instantAppInstallerActivity() == null) {
3117                             if (DEBUG_INSTANT) {
3118                                 Slog.v(TAG, "No installer - not adding it to the ResolveInfo"
3119                                         + "list");
3120                             }
3121                             resolveInfos.remove(i);
3122                             continue;
3123                         }
3124                         // requested service is defined in a split that hasn't been installed yet.
3125                         // add the installer to the resolve list
3126                         if (DEBUG_INSTANT) {
3127                             Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
3128                         }
3129                         final ResolveInfo installerInfo = new ResolveInfo(
3130                                 mInstantAppInstallerInfo);
3131                         installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
3132                                 null /* installFailureActivity */,
3133                                 info.serviceInfo.packageName,
3134                                 info.serviceInfo.applicationInfo.longVersionCode,
3135                                 info.serviceInfo.splitName);
3136                         // add a non-generic filter
3137                         installerInfo.filter = new IntentFilter();
3138                         // load resources from the correct package
3139                         installerInfo.resolvePackageName = info.getComponentInfo().packageName;
3140                         resolveInfos.set(i, installerInfo);
3141                     }
3142                     continue;
3143                 }
3144                 // allow services that have been explicitly exposed to ephemeral apps
3145                 if (!isEphemeralApp
3146                         && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP)
3147                                 != 0)) {
3148                     continue;
3149                 }
3150                 resolveInfos.remove(i);
3151             }
3152             return resolveInfos;
3153         }
3154 
filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, int userId)3155         private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
3156                 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
3157                 int userId) {
3158             final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
3159 
3160             if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
3161                 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
3162                         candidates.size());
3163             }
3164 
3165             final ArrayList<ResolveInfo> result =
3166                     filterCandidatesWithDomainPreferredActivitiesLPrBody(
3167                         intent, matchFlags, candidates, xpDomainInfo, userId, debug);
3168 
3169             if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
3170                 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: "
3171                         + result.size());
3172                 for (ResolveInfo info : result) {
3173                     Slog.v(TAG, "  + " + info.activityInfo);
3174                 }
3175             }
3176             return result;
3177         }
3178 
3179         /**
3180          * Filter out activities with systemUserOnly flag set, when current user is not System.
3181          *
3182          * @return filtered list
3183          */
filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId)3184         private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos,
3185                 int userId) {
3186             if (userId == UserHandle.USER_SYSTEM) {
3187                 return resolveInfos;
3188             }
3189             for (int i = resolveInfos.size() - 1; i >= 0; i--) {
3190                 ResolveInfo info = resolveInfos.get(i);
3191                 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
3192                     resolveInfos.remove(i);
3193                 }
3194             }
3195             return resolveInfos;
3196         }
3197 
maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent, String resolvedType, int flags, int userId, boolean resolveForStart, boolean isRequesterInstantApp)3198         private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result,
3199                 Intent intent,
3200                 String resolvedType, int flags, int userId, boolean resolveForStart,
3201                 boolean isRequesterInstantApp) {
3202             // first, check to see if we've got an instant app already installed
3203             final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
3204             ResolveInfo localInstantApp = null;
3205             boolean blockResolution = false;
3206             if (!alreadyResolvedLocally) {
3207                 final List<ResolveInfo> instantApps = mComponentResolver.queryActivities(
3208                         intent,
3209                         resolvedType,
3210                         flags
3211                             | PackageManager.GET_RESOLVED_FILTER
3212                             | PackageManager.MATCH_INSTANT
3213                             | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
3214                         userId);
3215                 for (int i = instantApps.size() - 1; i >= 0; --i) {
3216                     final ResolveInfo info = instantApps.get(i);
3217                     final String packageName = info.activityInfo.packageName;
3218                     final PackageSetting ps = mSettings.getPackageLPr(packageName);
3219                     if (ps.getInstantApp(userId)) {
3220                         if (hasAnyDomainApproval(mDomainVerificationManager, ps, intent, flags,
3221                                 userId)) {
3222                             if (DEBUG_INSTANT) {
3223                                 Slog.v(TAG, "Instant app approved for intent; pkg: "
3224                                         + packageName);
3225                             }
3226                             localInstantApp = info;
3227                         } else {
3228                             if (DEBUG_INSTANT) {
3229                                 Slog.v(TAG, "Instant app not approved for intent; pkg: "
3230                                         + packageName);
3231                             }
3232                             blockResolution = true;
3233                         }
3234                         break;
3235                     }
3236                 }
3237             }
3238             // no app installed, let's see if one's available
3239             AuxiliaryResolveInfo auxiliaryResponse = null;
3240             if (!blockResolution) {
3241                 if (localInstantApp == null) {
3242                     // we don't have an instant app locally, resolve externally
3243                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
3244                     String token = UUID.randomUUID().toString();
3245                     InstantAppDigest digest = InstantAppResolver.parseDigest(intent);
3246                     final InstantAppRequest requestObject =
3247                             new InstantAppRequest(null /*responseObj*/,
3248                             intent /*origIntent*/, resolvedType, null /*callingPackage*/,
3249                             null /*callingFeatureId*/, isRequesterInstantApp, userId,
3250                             null /*verificationBundle*/, resolveForStart,
3251                             digest.getDigestPrefixSecure(), token);
3252                     auxiliaryResponse = InstantAppResolver.doInstantAppResolutionPhaseOne(
3253                             mInstantAppResolverConnection, requestObject);
3254                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3255                 } else {
3256                     // we have an instant application locally, but, we can't admit that since
3257                     // callers shouldn't be able to determine prior browsing. create a placeholder
3258                     // auxiliary response so the downstream code behaves as if there's an
3259                     // instant application available externally. when it comes time to start
3260                     // the instant application, we'll do the right thing.
3261                     final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
3262                     auxiliaryResponse = new AuxiliaryResolveInfo(null /* failureActivity */,
3263                                             ai.packageName, ai.longVersionCode,
3264                             null /* splitName */);
3265                 }
3266             }
3267             if (intent.isWebIntent() && auxiliaryResponse == null) {
3268                 return result;
3269             }
3270             final PackageSetting ps =
3271                     mSettings.getPackageLPr(instantAppInstallerActivity().packageName);
3272             if (ps == null
3273                     || !ps.readUserState(userId).isEnabled(instantAppInstallerActivity(), 0)) {
3274                 return result;
3275             }
3276             final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
3277             ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
3278                     instantAppInstallerActivity(), 0, ps.readUserState(userId), userId);
3279             ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
3280                     | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
3281             // add a non-generic filter
3282             ephemeralInstaller.filter = new IntentFilter();
3283             if (intent.getAction() != null) {
3284                 ephemeralInstaller.filter.addAction(intent.getAction());
3285             }
3286             if (intent.getData() != null && intent.getData().getPath() != null) {
3287                 ephemeralInstaller.filter.addDataPath(
3288                         intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
3289             }
3290             ephemeralInstaller.isInstantAppAvailable = true;
3291             // make sure this resolver is the default
3292             ephemeralInstaller.isDefault = true;
3293             ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
3294             if (DEBUG_INSTANT) {
3295                 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
3296             }
3297 
3298             result.add(ephemeralInstaller);
3299             return result;
3300         }
3301 
generatePackageInfo(PackageSetting ps, int flags, int userId)3302         public final PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3303             if (!mUserManager.exists(userId)) return null;
3304             if (ps == null) {
3305                 return null;
3306             }
3307             final int callingUid = Binder.getCallingUid();
3308             // Filter out ephemeral app metadata:
3309             //   * The system/shell/root can see metadata for any app
3310             //   * An installed app can see metadata for 1) other installed apps
3311             //     and 2) ephemeral apps that have explicitly interacted with it
3312             //   * Ephemeral apps can only see their own data and exposed installed apps
3313             //   * Holding a signature permission allows seeing instant apps
3314             if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
3315                 return null;
3316             }
3317 
3318             if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3319                     && ps.isSystem()) {
3320                 flags |= MATCH_ANY_USER;
3321             }
3322 
3323             final PackageUserState state = ps.readUserState(userId);
3324             AndroidPackage p = ps.pkg;
3325             if (p != null) {
3326                 // Compute GIDs only if requested
3327                 final int[] gids = (flags & PackageManager.GET_GIDS) == 0 ? EMPTY_INT_ARRAY
3328                         : mPermissionManager.getGidsForUid(UserHandle.getUid(userId, ps.appId));
3329                 // Compute granted permissions only if package has requested permissions
3330                 final Set<String> permissions = ((flags & PackageManager.GET_PERMISSIONS) == 0
3331                         || ArrayUtils.isEmpty(p.getRequestedPermissions())) ? Collections.emptySet()
3332                         : mPermissionManager.getGrantedPermissions(ps.name, userId);
3333 
3334                 PackageInfo packageInfo = PackageInfoUtils.generate(p, gids, flags,
3335                         ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId, ps);
3336 
3337                 if (packageInfo == null) {
3338                     return null;
3339                 }
3340 
3341                 packageInfo.packageName = packageInfo.applicationInfo.packageName =
3342                         resolveExternalPackageNameLPr(p);
3343 
3344                 return packageInfo;
3345             } else if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 && state.isAvailable(flags)) {
3346                 PackageInfo pi = new PackageInfo();
3347                 pi.packageName = ps.name;
3348                 pi.setLongVersionCode(ps.versionCode);
3349                 pi.sharedUserId = (ps.sharedUser != null) ? ps.sharedUser.name : null;
3350                 pi.firstInstallTime = ps.firstInstallTime;
3351                 pi.lastUpdateTime = ps.lastUpdateTime;
3352 
3353                 ApplicationInfo ai = new ApplicationInfo();
3354                 ai.packageName = ps.name;
3355                 ai.uid = UserHandle.getUid(userId, ps.appId);
3356                 ai.primaryCpuAbi = ps.primaryCpuAbiString;
3357                 ai.secondaryCpuAbi = ps.secondaryCpuAbiString;
3358                 ai.setVersionCode(ps.versionCode);
3359                 ai.flags = ps.pkgFlags;
3360                 ai.privateFlags = ps.pkgPrivateFlags;
3361                 pi.applicationInfo =
3362                         PackageParser.generateApplicationInfo(ai, flags, state, userId);
3363 
3364                 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "ps.pkg is n/a for ["
3365                         + ps.name + "]. Provides a minimum info.");
3366                 return pi;
3367             } else {
3368                 return null;
3369             }
3370         }
3371 
getPackageInfo(String packageName, int flags, int userId)3372         public final PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3373             return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3374                     flags, Binder.getCallingUid(), userId);
3375         }
3376 
3377         /**
3378          * Important: The provided filterCallingUid is used exclusively to filter out packages
3379          * that can be seen based on user state. It's typically the original caller uid prior
3380          * to clearing. Because it can only be provided by trusted code, its value can be
3381          * trusted and will be used as-is; unlike userId which will be validated by this method.
3382          */
getPackageInfoInternal(String packageName, long versionCode, int flags, int filterCallingUid, int userId)3383         public final PackageInfo getPackageInfoInternal(String packageName, long versionCode,
3384                 int flags, int filterCallingUid, int userId) {
3385             if (!mUserManager.exists(userId)) return null;
3386             flags = updateFlagsForPackage(flags, userId);
3387             enforceCrossUserPermission(Binder.getCallingUid(), userId,
3388                     false /* requireFullPermission */, false /* checkShell */, "get package info");
3389 
3390             return getPackageInfoInternalBody(packageName, versionCode, flags, filterCallingUid,
3391                     userId);
3392         }
3393 
getPackageInfoInternalBody(String packageName, long versionCode, int flags, int filterCallingUid, int userId)3394         protected PackageInfo getPackageInfoInternalBody(String packageName, long versionCode,
3395                 int flags, int filterCallingUid, int userId) {
3396             // reader
3397             // Normalize package name to handle renamed packages and static libs
3398             packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3399 
3400             final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3401             if (matchFactoryOnly) {
3402                 // Instant app filtering for APEX modules is ignored
3403                 if ((flags & MATCH_APEX) != 0) {
3404                     return mApexManager.getPackageInfo(packageName,
3405                             ApexManager.MATCH_FACTORY_PACKAGE);
3406                 }
3407                 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3408                 if (ps != null) {
3409                     if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3410                         return null;
3411                     }
3412                     if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
3413                         return null;
3414                     }
3415                     return generatePackageInfo(ps, flags, userId);
3416                 }
3417             }
3418 
3419             AndroidPackage p = mPackages.get(packageName);
3420             if (matchFactoryOnly && p != null && !p.isSystem()) {
3421                 return null;
3422             }
3423             if (DEBUG_PACKAGE_INFO)
3424                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3425             if (p != null) {
3426                 final PackageSetting ps = getPackageSetting(p.getPackageName());
3427                 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3428                     return null;
3429                 }
3430                 if (ps != null && shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
3431                     return null;
3432                 }
3433 
3434                 return generatePackageInfo(ps, flags, userId);
3435             }
3436             if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3437                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
3438                 if (ps == null) return null;
3439                 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3440                     return null;
3441                 }
3442                 if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
3443                     return null;
3444                 }
3445                 return generatePackageInfo(ps, flags, userId);
3446             }
3447             if ((flags & MATCH_APEX) != 0) {
3448                 return mApexManager.getPackageInfo(packageName, ApexManager.MATCH_ACTIVE_PACKAGE);
3449             }
3450             return null;
3451         }
3452 
3453         @Nullable
getPackageSetting(String packageName)3454         public final PackageSetting getPackageSetting(String packageName) {
3455             return getPackageSettingInternal(packageName, Binder.getCallingUid());
3456         }
3457 
getPackageSettingInternal(String packageName, int callingUid)3458         public PackageSetting getPackageSettingInternal(String packageName, int callingUid) {
3459             packageName = resolveInternalPackageNameInternalLocked(
3460                     packageName, PackageManager.VERSION_CODE_HIGHEST, callingUid);
3461             return mSettings.getPackageLPr(packageName);
3462         }
3463 
getInstalledPackages(int flags, int userId)3464         public final ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
3465             final int callingUid = Binder.getCallingUid();
3466             if (getInstantAppPackageName(callingUid) != null) {
3467                 return ParceledListSlice.emptyList();
3468             }
3469             if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
3470             flags = updateFlagsForPackage(flags, userId);
3471 
3472             enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
3473                     false /* checkShell */, "get installed packages");
3474 
3475             return getInstalledPackagesBody(flags, userId, callingUid);
3476         }
3477 
getInstalledPackagesBody(int flags, int userId, int callingUid)3478         protected ParceledListSlice<PackageInfo> getInstalledPackagesBody(int flags, int userId,
3479                                                                           int callingUid) {
3480             // writer
3481             final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
3482             final boolean listApex = (flags & MATCH_APEX) != 0;
3483             final boolean listFactory = (flags & MATCH_FACTORY_ONLY) != 0;
3484 
3485             ArrayList<PackageInfo> list;
3486             if (listUninstalled) {
3487                 list = new ArrayList<>(mSettings.getPackagesLocked().size());
3488                 for (PackageSetting ps : mSettings.getPackagesLocked().values()) {
3489                     if (listFactory) {
3490                         if (!ps.isSystem()) {
3491                             continue;
3492                         }
3493                         PackageSetting psDisabled = mSettings.getDisabledSystemPkgLPr(ps);
3494                         if (psDisabled != null) {
3495                             ps = psDisabled;
3496                         }
3497                     }
3498                     if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
3499                         continue;
3500                     }
3501                     if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
3502                         continue;
3503                     }
3504                     final PackageInfo pi = generatePackageInfo(ps, flags, userId);
3505                     if (pi != null) {
3506                         list.add(pi);
3507                     }
3508                 }
3509             } else {
3510                 list = new ArrayList<>(mPackages.size());
3511                 for (AndroidPackage p : mPackages.values()) {
3512                     PackageSetting ps = getPackageSetting(p.getPackageName());
3513                     if (listFactory) {
3514                         if (!p.isSystem()) {
3515                             continue;
3516                         }
3517                         PackageSetting psDisabled = mSettings.getDisabledSystemPkgLPr(ps);
3518                         if (psDisabled != null) {
3519                             ps = psDisabled;
3520                         }
3521                     }
3522                     if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
3523                         continue;
3524                     }
3525                     if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
3526                         continue;
3527                     }
3528                     final PackageInfo pi = generatePackageInfo(ps, flags, userId);
3529                     if (pi != null) {
3530                         list.add(pi);
3531                     }
3532                 }
3533             }
3534             if (listApex) {
3535                 if (listFactory) {
3536                     list.addAll(mApexManager.getFactoryPackages());
3537                 } else {
3538                     list.addAll(mApexManager.getActivePackages());
3539                 }
3540                 if (listUninstalled) {
3541                     list.addAll(mApexManager.getInactivePackages());
3542                 }
3543             }
3544             return new ParceledListSlice<>(list);
3545         }
3546 
3547         /**
3548          * If the filter's target user can handle the intent and is enabled: a [ResolveInfo] that
3549          * will forward the intent to the filter's target user, along with the highest approval of
3550          * any handler in the target user. Otherwise, returns null.
3551          */
3552         @Nullable
createForwardingResolveInfo( @onNull CrossProfileIntentFilter filter, @NonNull Intent intent, @Nullable String resolvedType, int flags, int sourceUserId)3553         private CrossProfileDomainInfo createForwardingResolveInfo(
3554                 @NonNull CrossProfileIntentFilter filter, @NonNull Intent intent,
3555                 @Nullable String resolvedType, int flags, int sourceUserId) {
3556             int targetUserId = filter.getTargetUserId();
3557             if (!isUserEnabled(targetUserId)) {
3558                 return null;
3559             }
3560 
3561             List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent,
3562                     resolvedType, flags, targetUserId);
3563             if (CollectionUtils.isEmpty(resultTargetUser)) {
3564                 return null;
3565             }
3566 
3567             ResolveInfo forwardingInfo = null;
3568             for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
3569                 ResolveInfo targetUserResolveInfo = resultTargetUser.get(i);
3570                 if ((targetUserResolveInfo.activityInfo.applicationInfo.flags
3571                         & ApplicationInfo.FLAG_SUSPENDED) == 0) {
3572                     forwardingInfo = createForwardingResolveInfoUnchecked(filter, sourceUserId,
3573                             targetUserId);
3574                     break;
3575                 }
3576             }
3577 
3578             if (forwardingInfo == null) {
3579                 // If all the matches in the target profile are suspended, return null.
3580                 return null;
3581             }
3582 
3583             int highestApprovalLevel = DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE;
3584 
3585             int size = resultTargetUser.size();
3586             for (int i = 0; i < size; i++) {
3587                 ResolveInfo riTargetUser = resultTargetUser.get(i);
3588                 if (riTargetUser.handleAllWebDataURI) {
3589                     continue;
3590                 }
3591                 String packageName = riTargetUser.activityInfo.packageName;
3592                 PackageSetting ps = mSettings.getPackageLPr(packageName);
3593                 if (ps == null) {
3594                     continue;
3595                 }
3596                 highestApprovalLevel = Math.max(highestApprovalLevel, mDomainVerificationManager
3597                                 .approvalLevelForDomain(ps, intent, flags, targetUserId));
3598             }
3599 
3600             return new CrossProfileDomainInfo(forwardingInfo, highestApprovalLevel);
3601         }
3602 
createForwardingResolveInfoUnchecked(WatchedIntentFilter filter, int sourceUserId, int targetUserId)3603         public final ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
3604                 int sourceUserId, int targetUserId) {
3605             ResolveInfo forwardingResolveInfo = new ResolveInfo();
3606             final long ident = Binder.clearCallingIdentity();
3607             boolean targetIsProfile;
3608             try {
3609                 targetIsProfile = mUserManager.getUserInfo(targetUserId).isManagedProfile();
3610             } finally {
3611                 Binder.restoreCallingIdentity(ident);
3612             }
3613             String className;
3614             if (targetIsProfile) {
3615                 className = FORWARD_INTENT_TO_MANAGED_PROFILE;
3616             } else {
3617                 className = FORWARD_INTENT_TO_PARENT;
3618             }
3619             ComponentName forwardingActivityComponentName = new ComponentName(
3620                     androidApplication().packageName, className);
3621             ActivityInfo forwardingActivityInfo =
3622                     getActivityInfo(forwardingActivityComponentName, 0,
3623                     sourceUserId);
3624             if (!targetIsProfile) {
3625                 forwardingActivityInfo.showUserIcon = targetUserId;
3626                 forwardingResolveInfo.noResourceId = true;
3627             }
3628             forwardingResolveInfo.activityInfo = forwardingActivityInfo;
3629             forwardingResolveInfo.priority = 0;
3630             forwardingResolveInfo.preferredOrder = 0;
3631             forwardingResolveInfo.match = 0;
3632             forwardingResolveInfo.isDefault = true;
3633             forwardingResolveInfo.filter = new IntentFilter(filter.getIntentFilter());
3634             forwardingResolveInfo.targetUserId = targetUserId;
3635             return forwardingResolveInfo;
3636         }
3637 
3638         // Return matching ResolveInfo in target user if any.
3639         @Nullable
queryCrossProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId, boolean matchInCurrentProfile)3640         private CrossProfileDomainInfo queryCrossProfileIntents(
3641                 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
3642                 int flags, int sourceUserId, boolean matchInCurrentProfile) {
3643             if (matchingFilters == null) {
3644                 return null;
3645             }
3646             // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
3647             // match the same intent. For performance reasons, it is better not to
3648             // run queryIntent twice for the same userId
3649             SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
3650 
3651             CrossProfileDomainInfo resultInfo = null;
3652 
3653             int size = matchingFilters.size();
3654             for (int i = 0; i < size; i++) {
3655                 CrossProfileIntentFilter filter = matchingFilters.get(i);
3656                 int targetUserId = filter.getTargetUserId();
3657                 boolean skipCurrentProfile =
3658                         (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
3659                 boolean skipCurrentProfileIfNoMatchFound =
3660                         (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
3661                 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
3662                         && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
3663                     // Checking if there are activities in the target user that can handle the
3664                     // intent.
3665                     CrossProfileDomainInfo info = createForwardingResolveInfo(filter, intent,
3666                             resolvedType, flags, sourceUserId);
3667                     if (info != null) {
3668                         resultInfo = info;
3669                         break;
3670                     }
3671                     alreadyTriedUserIds.put(targetUserId, true);
3672                 }
3673             }
3674 
3675             if (resultInfo == null) {
3676                 return null;
3677             }
3678 
3679             ResolveInfo forwardingResolveInfo = resultInfo.resolveInfo;
3680             if (!isUserEnabled(forwardingResolveInfo.targetUserId)) {
3681                 return null;
3682             }
3683 
3684             List<ResolveInfo> filteredResult =
3685                     filterIfNotSystemUser(Collections.singletonList(forwardingResolveInfo),
3686                             sourceUserId);
3687             if (filteredResult.isEmpty()) {
3688                 return null;
3689             }
3690 
3691             return resultInfo;
3692         }
3693 
querySkipCurrentProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId)3694         private ResolveInfo querySkipCurrentProfileIntents(
3695                 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
3696                 int flags, int sourceUserId) {
3697             if (matchingFilters != null) {
3698                 int size = matchingFilters.size();
3699                 for (int i = 0; i < size; i ++) {
3700                     CrossProfileIntentFilter filter = matchingFilters.get(i);
3701                     if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
3702                         // Checking if there are activities in the target user that can handle the
3703                         // intent.
3704                         CrossProfileDomainInfo info = createForwardingResolveInfo(filter, intent,
3705                                 resolvedType, flags, sourceUserId);
3706                         if (info != null) {
3707                             return info.resolveInfo;
3708                         }
3709                     }
3710                 }
3711             }
3712             return null;
3713         }
3714 
getServiceInfo(ComponentName component, int flags, int userId)3715         public final ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
3716             if (!mUserManager.exists(userId)) return null;
3717             final int callingUid = Binder.getCallingUid();
3718             flags = updateFlagsForComponent(flags, userId);
3719             enforceCrossUserOrProfilePermission(callingUid, userId,
3720                     false /* requireFullPermission */,
3721                     false /* checkShell */, "get service info");
3722             return getServiceInfoBody(component, flags, userId, callingUid);
3723         }
3724 
getServiceInfoBody(ComponentName component, int flags, int userId, int callingUid)3725         protected ServiceInfo getServiceInfoBody(ComponentName component, int flags, int userId,
3726                                                  int callingUid) {
3727             ParsedService s = mComponentResolver.getService(component);
3728             if (DEBUG_PACKAGE_INFO) Log.v(
3729                     TAG, "getServiceInfo " + component + ": " + s);
3730             if (s == null) {
3731                 return null;
3732             }
3733 
3734             AndroidPackage pkg = mPackages.get(s.getPackageName());
3735             if (mSettings.isEnabledAndMatchLPr(pkg, s, flags, userId)) {
3736                 PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
3737                 if (ps == null) return null;
3738                 if (shouldFilterApplicationLocked(
3739                         ps, callingUid, component, TYPE_SERVICE, userId)) {
3740                     return null;
3741                 }
3742                 return PackageInfoUtils.generateServiceInfo(pkg,
3743                         s, flags, ps.readUserState(userId), userId, ps);
3744             }
3745             return null;
3746         }
3747 
3748         @Nullable
getSharedLibraryInfoLPr(String name, long version)3749         public final SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version) {
3750             return getSharedLibraryInfo(name, version, mSharedLibraries, null);
3751         }
3752 
3753         /**
3754          * Returns the package name of the calling Uid if it's an instant app. If it isn't
3755          * instant, returns {@code null}.
3756          */
getInstantAppPackageName(int callingUid)3757         public String getInstantAppPackageName(int callingUid) {
3758             // If the caller is an isolated app use the owner's uid for the lookup.
3759             if (Process.isIsolated(callingUid)) {
3760                 callingUid = getIsolatedOwner(callingUid);
3761             }
3762             final int appId = UserHandle.getAppId(callingUid);
3763             final Object obj = mSettings.getSettingLPr(appId);
3764             if (obj instanceof PackageSetting) {
3765                 final PackageSetting ps = (PackageSetting) obj;
3766                 final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
3767                 return isInstantApp ? ps.pkg.getPackageName() : null;
3768             }
3769             return null;
3770         }
3771 
3772         /**
3773          * Finds the owner for the provided isolated UID. Throws IllegalStateException if no such
3774          * isolated UID is found.
3775          */
getIsolatedOwner(int isolatedUid)3776         private int getIsolatedOwner(int isolatedUid) {
3777             final int ownerUid = mIsolatedOwners.get(isolatedUid, -1);
3778             if (ownerUid == -1) {
3779                 throw new IllegalStateException(
3780                         "No owner UID found for isolated UID " + isolatedUid);
3781             }
3782             return ownerUid;
3783         }
3784 
resolveExternalPackageNameLPr(AndroidPackage pkg)3785         public final String resolveExternalPackageNameLPr(AndroidPackage pkg) {
3786             if (pkg.getStaticSharedLibName() != null) {
3787                 return pkg.getManifestPackageName();
3788             }
3789             return pkg.getPackageName();
3790         }
3791 
resolveInternalPackageNameInternalLocked( String packageName, long versionCode, int callingUid)3792         private String resolveInternalPackageNameInternalLocked(
3793                 String packageName, long versionCode, int callingUid) {
3794             // Handle renamed packages
3795             String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
3796             packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
3797 
3798             // Is this a static library?
3799             WatchedLongSparseArray<SharedLibraryInfo> versionedLib =
3800                     mStaticLibsByDeclaringPackage.get(packageName);
3801             if (versionedLib == null || versionedLib.size() <= 0) {
3802                 return packageName;
3803             }
3804 
3805             // Figure out which lib versions the caller can see
3806             LongSparseLongArray versionsCallerCanSee = null;
3807             final int callingAppId = UserHandle.getAppId(callingUid);
3808             if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
3809                     && callingAppId != Process.ROOT_UID) {
3810                 versionsCallerCanSee = new LongSparseLongArray();
3811                 String libName = versionedLib.valueAt(0).getName();
3812                 String[] uidPackages = getPackagesForUidInternal(callingUid, callingUid);
3813                 if (uidPackages != null) {
3814                     for (String uidPackage : uidPackages) {
3815                         PackageSetting ps = mSettings.getPackageLPr(uidPackage);
3816                         final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
3817                         if (libIdx >= 0) {
3818                             final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
3819                             versionsCallerCanSee.append(libVersion, libVersion);
3820                         }
3821                     }
3822                 }
3823             }
3824 
3825             // Caller can see nothing - done
3826             if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
3827                 return packageName;
3828             }
3829 
3830             // Find the version the caller can see and the app version code
3831             SharedLibraryInfo highestVersion = null;
3832             final int versionCount = versionedLib.size();
3833             for (int i = 0; i < versionCount; i++) {
3834                 SharedLibraryInfo libraryInfo = versionedLib.valueAt(i);
3835                 if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
3836                         libraryInfo.getLongVersion()) < 0) {
3837                     continue;
3838                 }
3839                 final long libVersionCode = libraryInfo.getDeclaringPackage().getLongVersionCode();
3840                 if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
3841                     if (libVersionCode == versionCode) {
3842                         return libraryInfo.getPackageName();
3843                     }
3844                 } else if (highestVersion == null) {
3845                     highestVersion = libraryInfo;
3846                 } else if (libVersionCode  > highestVersion
3847                         .getDeclaringPackage().getLongVersionCode()) {
3848                     highestVersion = libraryInfo;
3849                 }
3850             }
3851 
3852             if (highestVersion != null) {
3853                 return highestVersion.getPackageName();
3854             }
3855 
3856             return packageName;
3857         }
3858 
resolveInternalPackageNameLPr(String packageName, long versionCode)3859         public final String resolveInternalPackageNameLPr(String packageName, long versionCode) {
3860             final int callingUid = Binder.getCallingUid();
3861             return resolveInternalPackageNameInternalLocked(packageName, versionCode,
3862                     callingUid);
3863         }
3864 
3865         /**
3866          * <em>IMPORTANT:</em> Not all packages returned by this method may be known
3867          * to the system. There are two conditions in which this may occur:
3868          * <ol>
3869          *   <li>The package is on adoptable storage and the device has been removed</li>
3870          *   <li>The package is being removed and the internal structures are partially updated</li>
3871          * </ol>
3872          * The second is an artifact of the current data structures and should be fixed. See
3873          * b/111075456 for one such instance.
3874          * This binder API is cached.  If the algorithm in this method changes,
3875          * or if the underlying objecs (as returned by getSettingLPr()) change
3876          * then the logic that invalidates the cache must be revisited.  See
3877          * calls to invalidateGetPackagesForUidCache() to locate the points at
3878          * which the cache is invalidated.
3879          */
getPackagesForUid(int uid)3880         public final String[] getPackagesForUid(int uid) {
3881             return getPackagesForUidInternal(uid, Binder.getCallingUid());
3882         }
3883 
getPackagesForUidInternal(int uid, int callingUid)3884         private String[] getPackagesForUidInternal(int uid, int callingUid) {
3885             final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
3886             final int userId = UserHandle.getUserId(uid);
3887             final int appId = UserHandle.getAppId(uid);
3888             return getPackagesForUidInternalBody(callingUid, userId, appId, isCallerInstantApp);
3889         }
3890 
getPackagesForUidInternalBody(int callingUid, int userId, int appId, boolean isCallerInstantApp)3891         protected String[] getPackagesForUidInternalBody(int callingUid, int userId, int appId,
3892                                                          boolean isCallerInstantApp) {
3893             // reader
3894             final Object obj = mSettings.getSettingLPr(appId);
3895             if (obj instanceof SharedUserSetting) {
3896                 if (isCallerInstantApp) {
3897                     return null;
3898                 }
3899                 final SharedUserSetting sus = (SharedUserSetting) obj;
3900                 final int N = sus.packages.size();
3901                 String[] res = new String[N];
3902                 int i = 0;
3903                 for (int index = 0; index < N; index++) {
3904                     final PackageSetting ps = sus.packages.valueAt(index);
3905                     if (ps.getInstalled(userId)
3906                             && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
3907                         res[i++] = ps.name;
3908                     }
3909                 }
3910                 return ArrayUtils.trimToSize(res, i);
3911             } else if (obj instanceof PackageSetting) {
3912                 final PackageSetting ps = (PackageSetting) obj;
3913                 if (ps.getInstalled(userId)
3914                         && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
3915                     return new String[]{ps.name};
3916                 }
3917             }
3918             return null;
3919         }
3920 
getProfileParent(int userId)3921         public final UserInfo getProfileParent(int userId) {
3922             final long identity = Binder.clearCallingIdentity();
3923             try {
3924                 return mUserManager.getProfileParent(userId);
3925             } finally {
3926                 Binder.restoreCallingIdentity(identity);
3927             }
3928         }
3929 
3930         /**
3931          * Returns whether or not instant apps have been disabled remotely.
3932          */
areWebInstantAppsDisabled(int userId)3933         private boolean areWebInstantAppsDisabled(int userId) {
3934             return mWebInstantAppsDisabled.get(userId);
3935         }
3936 
3937         /**
3938          * Returns whether or not a full application can see an instant application.
3939          * <p>
3940          * Currently, there are four cases in which this can occur:
3941          * <ol>
3942          * <li>The calling application is a "special" process. Special processes
3943          *     are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
3944          * <li>The calling application has the permission
3945          *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
3946          * <li>The calling application is the default launcher on the
3947          *     system partition.</li>
3948          * <li>The calling application is the default app prediction service.</li>
3949          * </ol>
3950          */
canViewInstantApps(int callingUid, int userId)3951         public final boolean canViewInstantApps(int callingUid, int userId) {
3952             if (callingUid < Process.FIRST_APPLICATION_UID) {
3953                 return true;
3954             }
3955             if (mContext.checkCallingOrSelfPermission(
3956                     android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3957                 return true;
3958             }
3959             if (mContext.checkCallingOrSelfPermission(
3960                     android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3961                 final ComponentName homeComponent = getDefaultHomeActivity(userId);
3962                 if (homeComponent != null
3963                         && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3964                     return true;
3965                 }
3966                 // TODO(b/122900055) Change/Remove this and replace with new permission role.
3967                 if (mAppPredictionServicePackage != null
3968                         && isCallerSameApp(mAppPredictionServicePackage, callingUid)) {
3969                     return true;
3970                 }
3971             }
3972             return false;
3973         }
3974 
filterSharedLibPackageLPr(@ullable PackageSetting ps, int uid, int userId, int flags)3975         public final boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid,
3976                 int userId, int flags) {
3977             // Callers can access only the libs they depend on, otherwise they need to explicitly
3978             // ask for the shared libraries given the caller is allowed to access all static libs.
3979             if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
3980                 // System/shell/root get to see all static libs
3981                 final int appId = UserHandle.getAppId(uid);
3982                 if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
3983                         || appId == Process.ROOT_UID) {
3984                     return false;
3985                 }
3986                 // Installer gets to see all static libs.
3987                 if (PackageManager.PERMISSION_GRANTED
3988                         == checkUidPermission(Manifest.permission.INSTALL_PACKAGES, uid)) {
3989                     return false;
3990                 }
3991             }
3992 
3993             // No package means no static lib as it is always on internal storage
3994             if (ps == null || ps.pkg == null || !ps.pkg.isStaticSharedLibrary()) {
3995                 return false;
3996             }
3997 
3998             final SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(
3999                     ps.pkg.getStaticSharedLibName(), ps.pkg.getStaticSharedLibVersion());
4000             if (libraryInfo == null) {
4001                 return false;
4002             }
4003 
4004             final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4005             final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4006             if (uidPackageNames == null) {
4007                 return true;
4008             }
4009 
4010             for (String uidPackageName : uidPackageNames) {
4011                 if (ps.name.equals(uidPackageName)) {
4012                     return false;
4013                 }
4014                 PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4015                 if (uidPs != null) {
4016                     final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4017                             libraryInfo.getName());
4018                     if (index < 0) {
4019                         continue;
4020                     }
4021                     if (uidPs.pkg.getUsesStaticLibrariesVersions()[index]
4022                             == libraryInfo.getLongVersion()) {
4023                         return false;
4024                     }
4025                 }
4026             }
4027             return true;
4028         }
4029 
hasCrossUserPermission( int callingUid, int callingUserId, int userId, boolean requireFullPermission, boolean requirePermissionWhenSameUser)4030         private boolean hasCrossUserPermission(
4031                 int callingUid, int callingUserId, int userId, boolean requireFullPermission,
4032                 boolean requirePermissionWhenSameUser) {
4033             if (!requirePermissionWhenSameUser && userId == callingUserId) {
4034                 return true;
4035             }
4036             if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) {
4037                 return true;
4038             }
4039             if (requireFullPermission) {
4040                 return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
4041             }
4042             return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
4043                     || hasPermission(Manifest.permission.INTERACT_ACROSS_USERS);
4044         }
4045 
4046         /**
4047          * @param resolveInfos list of resolve infos in descending priority order
4048          * @return if the list contains a resolve info with non-negative priority
4049          */
hasNonNegativePriority(List<ResolveInfo> resolveInfos)4050         private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
4051             return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
4052         }
4053 
hasPermission(String permission)4054         private boolean hasPermission(String permission) {
4055             return mContext.checkCallingOrSelfPermission(permission)
4056                     == PackageManager.PERMISSION_GRANTED;
4057         }
4058 
isCallerSameApp(String packageName, int uid)4059         public final boolean isCallerSameApp(String packageName, int uid) {
4060             AndroidPackage pkg = mPackages.get(packageName);
4061             return pkg != null
4062                     && UserHandle.getAppId(uid) == pkg.getUid();
4063         }
4064 
isComponentVisibleToInstantApp(@ullable ComponentName component)4065         public final boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
4066             if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
4067                 return true;
4068             }
4069             if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
4070                 return true;
4071             }
4072             if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
4073                 return true;
4074             }
4075             return false;
4076         }
4077 
isComponentVisibleToInstantApp( @ullable ComponentName component, @ComponentType int type)4078         public final boolean isComponentVisibleToInstantApp(
4079                 @Nullable ComponentName component, @ComponentType int type) {
4080             if (type == TYPE_ACTIVITY) {
4081                 final ParsedActivity activity = mComponentResolver.getActivity(component);
4082                 if (activity == null) {
4083                     return false;
4084                 }
4085                 final boolean visibleToInstantApp =
4086                         (activity.getFlags() & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4087                 final boolean explicitlyVisibleToInstantApp =
4088                         (activity.getFlags() & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP)
4089                         == 0;
4090                 return visibleToInstantApp && explicitlyVisibleToInstantApp;
4091             } else if (type == TYPE_RECEIVER) {
4092                 final ParsedActivity activity = mComponentResolver.getReceiver(component);
4093                 if (activity == null) {
4094                     return false;
4095                 }
4096                 final boolean visibleToInstantApp =
4097                         (activity.getFlags() & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4098                 final boolean explicitlyVisibleToInstantApp =
4099                         (activity.getFlags() & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP)
4100                         == 0;
4101                 return visibleToInstantApp && !explicitlyVisibleToInstantApp;
4102             } else if (type == TYPE_SERVICE) {
4103                 final ParsedService service = mComponentResolver.getService(component);
4104                 return service != null
4105                         && (service.getFlags() & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4106             } else if (type == TYPE_PROVIDER) {
4107                 final ParsedProvider provider = mComponentResolver.getProvider(component);
4108                 return provider != null
4109                         && (provider.getFlags() & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4110             } else if (type == TYPE_UNKNOWN) {
4111                 return isComponentVisibleToInstantApp(component);
4112             }
4113             return false;
4114         }
4115 
4116         /**
4117          * From Android R,
4118          *  camera intents have to match system apps. The only exception to this is if
4119          * the DPC has set the camera persistent preferred activity. This case was introduced
4120          * because it is important that the DPC has the ability to set both system and non-system
4121          * camera persistent preferred activities.
4122          *
4123          * @return {@code true} if the intent is a camera intent and the persistent preferred
4124          * activity was not set by the DPC.
4125          */
isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId, String resolvedType, int flags)4126         public final boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent,
4127                 int userId, String resolvedType, int flags) {
4128             return intent.isImplicitImageCaptureIntent() && !isPersistentPreferredActivitySetByDpm(
4129                     intent, userId, resolvedType, flags);
4130         }
4131 
isInstantApp(String packageName, int userId)4132         public final boolean isInstantApp(String packageName, int userId) {
4133             final int callingUid = Binder.getCallingUid();
4134             enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
4135                     false /* checkShell */, "isInstantApp");
4136 
4137             return isInstantAppInternal(packageName, userId, callingUid);
4138         }
4139 
isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid)4140         public final boolean isInstantAppInternal(String packageName, @UserIdInt int userId,
4141                 int callingUid) {
4142             if (HIDE_EPHEMERAL_APIS) {
4143                 return false;
4144             }
4145             return isInstantAppInternalBody(packageName, userId, callingUid);
4146         }
4147 
isInstantAppInternalBody(String packageName, @UserIdInt int userId, int callingUid)4148         protected boolean isInstantAppInternalBody(String packageName, @UserIdInt int userId,
4149                 int callingUid) {
4150             if (Process.isIsolated(callingUid)) {
4151                 callingUid = getIsolatedOwner(callingUid);
4152             }
4153             final PackageSetting ps = mSettings.getPackageLPr(packageName);
4154             final boolean returnAllowed =
4155                     ps != null
4156                     && (isCallerSameApp(packageName, callingUid)
4157                             || canViewInstantApps(callingUid, userId)
4158                             || mInstantAppRegistry.isInstantAccessGranted(
4159                                     userId, UserHandle.getAppId(callingUid), ps.appId));
4160             if (returnAllowed) {
4161                 return ps.getInstantApp(userId);
4162             }
4163             return false;
4164         }
4165 
isInstantAppResolutionAllowed( Intent intent, List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck, int flags)4166         private boolean isInstantAppResolutionAllowed(
4167                 Intent intent, List<ResolveInfo> resolvedActivities, int userId,
4168                 boolean skipPackageCheck, int flags) {
4169             if (mInstantAppResolverConnection == null) {
4170                 return false;
4171             }
4172             if (instantAppInstallerActivity() == null) {
4173                 return false;
4174             }
4175             if (intent.getComponent() != null) {
4176                 return false;
4177             }
4178             if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
4179                 return false;
4180             }
4181             if (!skipPackageCheck && intent.getPackage() != null) {
4182                 return false;
4183             }
4184             if (!intent.isWebIntent()) {
4185                 // for non web intents, we should not resolve externally if an app already exists to
4186                 // handle it or if the caller didn't explicitly request it.
4187                 if ((resolvedActivities != null && resolvedActivities.size() != 0)
4188                         || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) == 0) {
4189                     return false;
4190                 }
4191             } else {
4192                 if (intent.getData() == null || TextUtils.isEmpty(intent.getData().getHost())) {
4193                     return false;
4194                 } else if (areWebInstantAppsDisabled(userId)) {
4195                     return false;
4196                 }
4197             }
4198             // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
4199             // Or if there's already an ephemeral app installed that handles the action
4200             return isInstantAppResolutionAllowedBody(intent, resolvedActivities, userId,
4201                                                        skipPackageCheck, flags);
4202         }
4203 
4204         // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
4205         // Or if there's already an ephemeral app installed that handles the action
isInstantAppResolutionAllowedBody( Intent intent, List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck, int flags)4206         protected boolean isInstantAppResolutionAllowedBody(
4207                 Intent intent, List<ResolveInfo> resolvedActivities, int userId,
4208                 boolean skipPackageCheck, int flags) {
4209             final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
4210             for (int n = 0; n < count; n++) {
4211                 final ResolveInfo info = resolvedActivities.get(n);
4212                 final String packageName = info.activityInfo.packageName;
4213                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
4214                 if (ps != null) {
4215                     // only check domain verification status if the app is not a browser
4216                     if (!info.handleAllWebDataURI) {
4217                         if (hasAnyDomainApproval(mDomainVerificationManager, ps, intent, flags,
4218                                 userId)) {
4219                             if (DEBUG_INSTANT) {
4220                                 Slog.v(TAG, "DENY instant app;" + " pkg: " + packageName
4221                                         + ", approved");
4222                             }
4223                             return false;
4224                         }
4225                     }
4226                     if (ps.getInstantApp(userId)) {
4227                         if (DEBUG_INSTANT) {
4228                             Slog.v(TAG, "DENY instant app installed;"
4229                                     + " pkg: " + packageName);
4230                         }
4231                         return false;
4232                     }
4233                 }
4234             }
4235             // We've exhausted all ways to deny ephemeral application; let the system look for them.
4236             return true;
4237         }
4238 
isPersistentPreferredActivitySetByDpm(Intent intent, int userId, String resolvedType, int flags)4239         private boolean isPersistentPreferredActivitySetByDpm(Intent intent, int userId,
4240                 String resolvedType, int flags) {
4241             PersistentPreferredIntentResolver ppir =
4242                     mSettings.getPersistentPreferredActivities(userId);
4243             //TODO(b/158003772): Remove double query
4244             List<PersistentPreferredActivity> pprefs = ppir != null
4245                     ? ppir.queryIntent(intent, resolvedType,
4246                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
4247                     userId)
4248                     : new ArrayList<>();
4249             for (PersistentPreferredActivity ppa : pprefs) {
4250                 if (ppa.mIsSetByDpm) {
4251                     return true;
4252                 }
4253             }
4254             return false;
4255         }
4256 
isRecentsAccessingChildProfiles(int callingUid, int targetUserId)4257         private boolean isRecentsAccessingChildProfiles(int callingUid, int targetUserId) {
4258             if (!mInjector.getLocalService(ActivityTaskManagerInternal.class)
4259                     .isCallerRecents(callingUid)) {
4260                 return false;
4261             }
4262             final long token = Binder.clearCallingIdentity();
4263             try {
4264                 final int callingUserId = UserHandle.getUserId(callingUid);
4265                 if (ActivityManager.getCurrentUser() != callingUserId) {
4266                     return false;
4267                 }
4268                 return mUserManager.isSameProfileGroup(callingUserId, targetUserId);
4269             } finally {
4270                 Binder.restoreCallingIdentity(token);
4271             }
4272         }
4273 
isSameProfileGroup(@serIdInt int callerUserId, @UserIdInt int userId)4274         public final boolean isSameProfileGroup(@UserIdInt int callerUserId,
4275                 @UserIdInt int userId) {
4276             final long identity = Binder.clearCallingIdentity();
4277             try {
4278                 return UserManagerService.getInstance().isSameProfileGroup(callerUserId, userId);
4279             } finally {
4280                 Binder.restoreCallingIdentity(identity);
4281             }
4282         }
4283 
isUserEnabled(int userId)4284         private boolean isUserEnabled(int userId) {
4285             final long callingId = Binder.clearCallingIdentity();
4286             try {
4287                 UserInfo userInfo = mUserManager.getUserInfo(userId);
4288                 return userInfo != null && userInfo.isEnabled();
4289             } finally {
4290                 Binder.restoreCallingIdentity(callingId);
4291             }
4292         }
4293 
4294         /**
4295          * Returns whether or not access to the application should be filtered.
4296          * <p>
4297          * Access may be limited based upon whether the calling or target applications
4298          * are instant applications.
4299          *
4300          * @see #canViewInstantApps(int, int)
4301          */
shouldFilterApplicationLocked(@ullable PackageSetting ps, int callingUid, @Nullable ComponentName component, @ComponentType int componentType, int userId)4302         public final boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps,
4303                 int callingUid,
4304                 @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4305             // if we're in an isolated process, get the real calling UID
4306             if (Process.isIsolated(callingUid)) {
4307                 callingUid = getIsolatedOwner(callingUid);
4308             }
4309             final String instantAppPkgName = getInstantAppPackageName(callingUid);
4310             final boolean callerIsInstantApp = instantAppPkgName != null;
4311             if (ps == null) {
4312                 if (callerIsInstantApp) {
4313                     // pretend the application exists, but, needs to be filtered
4314                     return true;
4315                 }
4316                 return false;
4317             }
4318             // if the target and caller are the same application, don't filter
4319             if (isCallerSameApp(ps.name, callingUid)) {
4320                 return false;
4321             }
4322             if (callerIsInstantApp) {
4323                 // both caller and target are both instant, but, different applications, filter
4324                 if (ps.getInstantApp(userId)) {
4325                     return true;
4326                 }
4327                 // request for a specific component; if it hasn't been explicitly exposed through
4328                 // property or instrumentation target, filter
4329                 if (component != null) {
4330                     final ParsedInstrumentation instrumentation =
4331                             mInstrumentation.get(component);
4332                     if (instrumentation != null
4333                             && isCallerSameApp(instrumentation.getTargetPackage(), callingUid)) {
4334                         return false;
4335                     }
4336                     return !isComponentVisibleToInstantApp(component, componentType);
4337                 }
4338                 // request for application; if no components have been explicitly exposed, filter
4339                 return !ps.pkg.isVisibleToInstantApps();
4340             }
4341             if (ps.getInstantApp(userId)) {
4342                 // caller can see all components of all instant applications, don't filter
4343                 if (canViewInstantApps(callingUid, userId)) {
4344                     return false;
4345                 }
4346                 // request for a specific instant application component, filter
4347                 if (component != null) {
4348                     return true;
4349                 }
4350                 // request for an instant application; if the caller hasn't been granted access,
4351                 //filter
4352                 return !mInstantAppRegistry.isInstantAccessGranted(
4353                         userId, UserHandle.getAppId(callingUid), ps.appId);
4354             }
4355             int appId = UserHandle.getAppId(callingUid);
4356             final SettingBase callingPs = mSettings.getSettingLPr(appId);
4357             return mAppsFilter.shouldFilterApplication(callingUid, callingPs, ps, userId);
4358         }
4359 
4360         /**
4361          * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
4362          */
shouldFilterApplicationLocked( @ullable PackageSetting ps, int callingUid, int userId)4363         public final boolean shouldFilterApplicationLocked(
4364                 @Nullable PackageSetting ps, int callingUid, int userId) {
4365             return shouldFilterApplicationLocked(ps, callingUid, null, TYPE_UNKNOWN, userId);
4366         }
4367 
4368         /**
4369          * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
4370          */
shouldFilterApplicationLocked(@onNull SharedUserSetting sus, int callingUid, int userId)4371         public final boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus,
4372                 int callingUid, int userId) {
4373             boolean filterApp = true;
4374             for (int index = sus.packages.size() - 1; index >= 0 && filterApp; index--) {
4375                 filterApp &= shouldFilterApplicationLocked(sus.packages.valueAt(index),
4376                         callingUid, /* component */ null, TYPE_UNKNOWN, userId);
4377             }
4378             return filterApp;
4379         }
4380 
4381         /**
4382          * Verification statuses are ordered from the worse to the best, except for
4383          * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
4384          */
bestDomainVerificationStatus(int status1, int status2)4385         private int bestDomainVerificationStatus(int status1, int status2) {
4386             if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
4387                 return status2;
4388             }
4389             if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
4390                 return status1;
4391             }
4392             return (int) MathUtils.max(status1, status2);
4393         }
4394 
4395         // NOTE: Can't remove without a major refactor. Keep around for now.
checkUidPermission(String permName, int uid)4396         public final int checkUidPermission(String permName, int uid) {
4397             return mPermissionManager.checkUidPermission(uid, permName);
4398         }
4399 
getPackageUidInternal(String packageName, int flags, int userId, int callingUid)4400         public int getPackageUidInternal(String packageName, int flags, int userId,
4401                 int callingUid) {
4402             // reader
4403             final AndroidPackage p = mPackages.get(packageName);
4404             if (p != null && AndroidPackageUtils.isMatchForSystemOnly(p, flags)) {
4405                 PackageSetting ps = getPackageSettingInternal(p.getPackageName(), callingUid);
4406                 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
4407                     return -1;
4408                 }
4409                 return UserHandle.getUid(userId, p.getUid());
4410             }
4411             if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4412                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
4413                 if (ps != null && ps.isMatch(flags)
4414                         && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
4415                     return UserHandle.getUid(userId, ps.appId);
4416                 }
4417             }
4418 
4419             return -1;
4420         }
4421 
4422         /**
4423          * Update given flags based on encryption status of current user.
4424          */
updateFlags(int flags, int userId)4425         private int updateFlags(int flags, int userId) {
4426             if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4427                     | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4428                 // Caller expressed an explicit opinion about what encryption
4429                 // aware/unaware components they want to see, so fall through and
4430                 // give them what they want
4431             } else {
4432                 final UserManagerInternal umInternal = mInjector.getUserManagerInternal();
4433                 // Caller expressed no opinion, so match based on user state
4434                 if (umInternal.isUserUnlockingOrUnlocked(userId)) {
4435                     flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4436                 } else {
4437                     flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4438                 }
4439             }
4440             return flags;
4441         }
4442 
4443         /**
4444          * Update given flags when being used to request {@link ApplicationInfo}.
4445          */
updateFlagsForApplication(int flags, int userId)4446         public final int updateFlagsForApplication(int flags, int userId) {
4447             return updateFlagsForPackage(flags, userId);
4448         }
4449 
4450         /**
4451          * Update given flags when being used to request {@link ComponentInfo}.
4452          */
updateFlagsForComponent(int flags, int userId)4453         public final int updateFlagsForComponent(int flags, int userId) {
4454             return updateFlags(flags, userId);
4455         }
4456 
4457         /**
4458          * Update given flags when being used to request {@link PackageInfo}.
4459          */
updateFlagsForPackage(int flags, int userId)4460         public final int updateFlagsForPackage(int flags, int userId) {
4461             final boolean isCallerSystemUser = UserHandle.getCallingUserId()
4462                                                == UserHandle.USER_SYSTEM;
4463             if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4464                 // require the permission to be held; the calling uid and given user id referring
4465                 // to the same user is not sufficient
4466                 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
4467                         !isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId),
4468                         "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission");
4469             } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0
4470                     && isCallerSystemUser
4471                     && mUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4472                 // If the caller wants all packages and has a restricted profile associated with it,
4473                 // then match all users. This is to make sure that launchers that need to access
4474                 //work
4475                 // profile apps don't start breaking. TODO: Remove this hack when launchers stop
4476                 //using
4477                 // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4478                 flags |= PackageManager.MATCH_ANY_USER;
4479             }
4480             return updateFlags(flags, userId);
4481         }
4482 
4483         /**
4484          * Update given flags when being used to request {@link ResolveInfo}.
4485          * <p>Instant apps are resolved specially, depending upon context. Minimally,
4486          * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4487          * flag set. However, this flag is only honoured in three circumstances:
4488          * <ul>
4489          * <li>when called from a system process</li>
4490          * <li>when the caller holds the permission {@code
4491          * android.permission.ACCESS_INSTANT_APPS}</li>
4492          * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4493          * action and a {@code android.intent.category.BROWSABLE} category</li>
4494          * </ul>
4495          */
updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc)4496         public final int updateFlagsForResolve(int flags, int userId, int callingUid,
4497                 boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
4498             return updateFlagsForResolve(flags, userId, callingUid,
4499                     wantInstantApps, false /*onlyExposedExplicitly*/,
4500                     isImplicitImageCaptureIntentAndNotSetByDpc);
4501         }
4502 
updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc)4503         public final int updateFlagsForResolve(int flags, int userId, int callingUid,
4504                 boolean wantInstantApps, boolean onlyExposedExplicitly,
4505                 boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
4506             // Safe mode means we shouldn't match any third-party components
4507             if (safeMode() || isImplicitImageCaptureIntentAndNotSetByDpc) {
4508                 flags |= PackageManager.MATCH_SYSTEM_ONLY;
4509             }
4510             if (getInstantAppPackageName(callingUid) != null) {
4511                 // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4512                 if (onlyExposedExplicitly) {
4513                     flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4514                 }
4515                 flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4516                 flags |= PackageManager.MATCH_INSTANT;
4517             } else {
4518                 final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4519                 final boolean allowMatchInstant = wantInstantApps
4520                         || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4521                 flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4522                         | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4523                 if (!allowMatchInstant) {
4524                     flags &= ~PackageManager.MATCH_INSTANT;
4525                 }
4526             }
4527             return updateFlagsForComponent(flags, userId);
4528         }
4529 
4530         /**
4531          * Checks if the request is from the system or an app that has the appropriate cross-user
4532          * permissions defined as follows:
4533          * <ul>
4534          * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li>
4535          * <li>INTERACT_ACROSS_USERS if the given {@code userId} is in a different profile group
4536          * to the caller.</li>
4537          * <li>Otherwise,
4538          *  INTERACT_ACROSS_PROFILES if the given {@code userId} is in the same profile
4539          * group as the caller.</li>
4540          * </ul>
4541          *
4542          * @param checkShell whether to prevent shell from access if there's a debugging restriction
4543          * @param message the message to log on security exception
4544          */
enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message)4545         public final void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
4546                 boolean requireFullPermission, boolean checkShell, String message) {
4547             if (userId < 0) {
4548                 throw new IllegalArgumentException("Invalid userId " + userId);
4549             }
4550             if (checkShell) {
4551                 PackageManagerServiceUtils.enforceShellRestriction(
4552                         mInjector.getUserManagerInternal(),
4553                         UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4554             }
4555             final int callingUserId = UserHandle.getUserId(callingUid);
4556             if (hasCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission,
4557                     /*requirePermissionWhenSameUser= */ false)) {
4558                 return;
4559             }
4560             final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId);
4561             if (isSameProfileGroup && PermissionChecker.checkPermissionForPreflight(
4562                     mContext,
4563                     android.Manifest.permission.INTERACT_ACROSS_PROFILES,
4564                     PermissionChecker.PID_UNKNOWN,
4565                     callingUid,
4566                     getPackage(callingUid).getPackageName())
4567                     == PermissionChecker.PERMISSION_GRANTED) {
4568                 return;
4569             }
4570             String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage(
4571                     callingUid, userId, message, requireFullPermission, isSameProfileGroup);
4572             Slog.w(TAG, errorMessage);
4573             throw new SecurityException(errorMessage);
4574         }
4575 
4576         /**
4577          * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
4578          * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller.
4579          *
4580          * @param checkShell whether to prevent shell from access if there's a debugging restriction
4581          * @param message the message to log on security exception
4582          */
enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message)4583         public final void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
4584                 boolean requireFullPermission, boolean checkShell, String message) {
4585             enforceCrossUserPermission(callingUid, userId, requireFullPermission, checkShell, false,
4586                     message);
4587         }
4588 
4589         /**
4590          * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
4591          * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller.
4592          *
4593          * @param checkShell whether to prevent shell from access if there's a debugging restriction
4594          * @param requirePermissionWhenSameUser When {@code true}, still require the cross user
4595          *                                      permission to be held even if the callingUid and
4596          * userId
4597          *                                      reference the same user.
4598          * @param message the message to log on security exception
4599          */
enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, String message)4600         public final void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
4601                 boolean requireFullPermission, boolean checkShell,
4602                 boolean requirePermissionWhenSameUser, String message) {
4603             if (userId < 0) {
4604                 throw new IllegalArgumentException("Invalid userId " + userId);
4605             }
4606             if (checkShell) {
4607                 PackageManagerServiceUtils.enforceShellRestriction(
4608                         mInjector.getUserManagerInternal(),
4609                         UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4610             }
4611             final int callingUserId = UserHandle.getUserId(callingUid);
4612             if (hasCrossUserPermission(
4613                     callingUid, callingUserId, userId, requireFullPermission,
4614                     requirePermissionWhenSameUser)) {
4615                 return;
4616             }
4617             String errorMessage = buildInvalidCrossUserPermissionMessage(
4618                     callingUid, userId, message, requireFullPermission);
4619             Slog.w(TAG, errorMessage);
4620             throw new SecurityException(errorMessage);
4621         }
4622 
getSigningDetails(@onNull String packageName)4623         public SigningDetails getSigningDetails(@NonNull String packageName) {
4624             AndroidPackage p = mPackages.get(packageName);
4625             if (p == null) {
4626                 return null;
4627             }
4628             return p.getSigningDetails();
4629         }
4630 
getSigningDetails(int uid)4631         public SigningDetails getSigningDetails(int uid) {
4632             final int appId = UserHandle.getAppId(uid);
4633             final Object obj = mSettings.getSettingLPr(appId);
4634             if (obj != null) {
4635                 if (obj instanceof SharedUserSetting) {
4636                     return ((SharedUserSetting) obj).signatures.mSigningDetails;
4637                 } else if (obj instanceof PackageSetting) {
4638                     final PackageSetting ps = (PackageSetting) obj;
4639                     return ps.signatures.mSigningDetails;
4640                 }
4641             }
4642             return SigningDetails.UNKNOWN;
4643         }
4644 
filterAppAccess(AndroidPackage pkg, int callingUid, int userId)4645         public boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
4646             PackageSetting ps = getPackageSetting(pkg.getPackageName());
4647             return shouldFilterApplicationLocked(ps, callingUid,
4648                     userId);
4649         }
4650 
filterAppAccess(String packageName, int callingUid, int userId)4651         public boolean filterAppAccess(String packageName, int callingUid, int userId) {
4652             PackageSetting ps = getPackageSetting(packageName);
4653             return shouldFilterApplicationLocked(ps, callingUid,
4654                     userId);
4655         }
4656 
dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState)4657         public void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) {
4658             final String packageName = dumpState.getTargetPackageName();
4659             final boolean checkin = dumpState.isCheckIn();
4660 
4661             switch (type) {
4662                 case DumpState.DUMP_VERSION:
4663                 {
4664                     if (dumpState.onTitlePrinted()) {
4665                         pw.println();
4666                     }
4667                     pw.println("Database versions:");
4668                     mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
4669                     break;
4670                 }
4671 
4672                 case DumpState.DUMP_LIBS:
4673                 {
4674                     boolean printedHeader = false;
4675                     final int numSharedLibraries = mSharedLibraries.size();
4676                     for (int index = 0; index < numSharedLibraries; index++) {
4677                         final String libName = mSharedLibraries.keyAt(index);
4678                         final WatchedLongSparseArray<SharedLibraryInfo> versionedLib =
4679                                 mSharedLibraries.get(libName);
4680                         if (versionedLib == null) {
4681                             continue;
4682                         }
4683                         final int versionCount = versionedLib.size();
4684                         for (int i = 0; i < versionCount; i++) {
4685                             SharedLibraryInfo libraryInfo = versionedLib.valueAt(i);
4686                             if (!checkin) {
4687                                 if (!printedHeader) {
4688                                     if (dumpState.onTitlePrinted()) {
4689                                         pw.println();
4690                                     }
4691                                     pw.println("Libraries:");
4692                                     printedHeader = true;
4693                                 }
4694                                 pw.print("  ");
4695                             } else {
4696                                 pw.print("lib,");
4697                             }
4698                             pw.print(libraryInfo.getName());
4699                             if (libraryInfo.isStatic()) {
4700                                 pw.print(" version=" + libraryInfo.getLongVersion());
4701                             }
4702                             if (!checkin) {
4703                                 pw.print(" -> ");
4704                             }
4705                             if (libraryInfo.getPath() != null) {
4706                                 if (libraryInfo.isNative()) {
4707                                     pw.print(" (so) ");
4708                                 } else {
4709                                     pw.print(" (jar) ");
4710                                 }
4711                                 pw.print(libraryInfo.getPath());
4712                             } else {
4713                                 pw.print(" (apk) ");
4714                                 pw.print(libraryInfo.getPackageName());
4715                             }
4716                             pw.println();
4717                         }
4718                     }
4719                     break;
4720                 }
4721 
4722                 case DumpState.DUMP_PREFERRED:
4723                     mSettings.dumpPreferred(pw, dumpState, packageName);
4724                     break;
4725 
4726                 case DumpState.DUMP_PREFERRED_XML:
4727                 {
4728                     pw.flush();
4729                     FileOutputStream fout = new FileOutputStream(fd);
4730                     BufferedOutputStream str = new BufferedOutputStream(fout);
4731                     TypedXmlSerializer serializer = Xml.newFastSerializer();
4732                     try {
4733                         serializer.setOutput(str, StandardCharsets.UTF_8.name());
4734                         serializer.startDocument(null, true);
4735                         serializer.setFeature(
4736                                 "http://xmlpull.org/v1/doc/features.html#indent-output", true);
4737                         mSettings.writePreferredActivitiesLPr(serializer, 0,
4738                                 dumpState.isFullPreferred());
4739                         serializer.endDocument();
4740                         serializer.flush();
4741                     } catch (IllegalArgumentException e) {
4742                         pw.println("Failed writing: " + e);
4743                     } catch (IllegalStateException e) {
4744                         pw.println("Failed writing: " + e);
4745                     } catch (IOException e) {
4746                         pw.println("Failed writing: " + e);
4747                     }
4748                     break;
4749                 }
4750 
4751                 case DumpState.DUMP_QUERIES:
4752                 {
4753                     final PackageSetting setting = mSettings.getPackageLPr(packageName);
4754                     Integer filteringAppId = setting == null ? null : setting.appId;
4755                     mAppsFilter.dumpQueries(
4756                             pw, filteringAppId, dumpState, mUserManager.getUserIds(),
4757                             this::getPackagesForUidInternalBody);
4758                     break;
4759                 }
4760 
4761                 case DumpState.DUMP_DOMAIN_PREFERRED:
4762                 {
4763                     final android.util.IndentingPrintWriter writer =
4764                             new android.util.IndentingPrintWriter(pw);
4765                     if (dumpState.onTitlePrinted()) pw.println();
4766 
4767                     writer.println("Domain verification status:");
4768                     writer.increaseIndent();
4769                     try {
4770                         mDomainVerificationManager.printState(writer, packageName,
4771                                 UserHandle.USER_ALL, mSettings::getPackageLPr);
4772                     } catch (PackageManager.NameNotFoundException e) {
4773                         pw.println("Failure printing domain verification information");
4774                         Slog.e(TAG, "Failure printing domain verification information", e);
4775                     }
4776                     writer.decreaseIndent();
4777                     break;
4778                 }
4779 
4780                 case DumpState.DUMP_DEXOPT:
4781                 {
4782                     final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
4783                     ipw.println();
4784                     ipw.println("Dexopt state:");
4785                     ipw.increaseIndent();
4786                     Collection<PackageSetting> pkgSettings;
4787                     if (packageName != null) {
4788                         PackageSetting targetPkgSetting = mSettings.getPackageLPr(packageName);
4789                         if (targetPkgSetting != null) {
4790                             pkgSettings = Collections.singletonList(targetPkgSetting);
4791                         } else {
4792                             ipw.println("Unable to find package: " + packageName);
4793                             return;
4794                         }
4795                     } else {
4796                         pkgSettings = mSettings.getPackagesLocked().values();
4797                     }
4798 
4799                     for (PackageSetting pkgSetting : pkgSettings) {
4800                         final AndroidPackage pkg = pkgSetting.getPkg();
4801                         if (pkg == null) {
4802                             continue;
4803                         }
4804                         ipw.println("[" + pkgSetting.name + "]");
4805                         ipw.increaseIndent();
4806                         mPackageDexOptimizer.dumpDexoptState(ipw, pkg, pkgSetting,
4807                                 mDexManager.getPackageUseInfoOrDefault(pkg.getPackageName()));
4808                         ipw.decreaseIndent();
4809                     }
4810                     break;
4811                 }
4812 
4813                 case DumpState.DUMP_COMPILER_STATS:
4814                 {
4815                     final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
4816                     ipw.println();
4817                     ipw.println("Compiler stats:");
4818                     ipw.increaseIndent();
4819                     Collection<AndroidPackage> packages;
4820                     if (packageName != null) {
4821                         AndroidPackage targetPackage = mPackages.get(packageName);
4822                         if (targetPackage != null) {
4823                             packages = Collections.singletonList(targetPackage);
4824                         } else {
4825                             ipw.println("Unable to find package: " + packageName);
4826                             return;
4827                         }
4828                     } else {
4829                         packages = mPackages.values();
4830                     }
4831 
4832                     for (AndroidPackage pkg : packages) {
4833                         final String pkgName = pkg.getPackageName();
4834                         ipw.println("[" + pkgName + "]");
4835                         ipw.increaseIndent();
4836 
4837                         CompilerStats.PackageStats stats = mCompilerStats.getPackageStats(pkgName);
4838                         if (stats == null) {
4839                             ipw.println("(No recorded stats)");
4840                         } else {
4841                             stats.dump(ipw);
4842                         }
4843                         ipw.decreaseIndent();
4844                     }
4845                     break;
4846                 }
4847             } // switch
4848         }
4849     }
4850 
4851     /**
4852      * This subclass is the external interface to the live computer.  Some internal helper
4853      * methods are overridden to fetch live data instead of snapshot data.  For each
4854      * Computer interface that is overridden in this class, the override takes the PM lock
4855      * and then delegates to the live computer engine.  This is required because there are
4856      * no locks taken in the engine itself.
4857      */
4858     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
4859     protected static class ComputerLocked extends ComputerEngine {
4860         private final Object mLock;
4861 
ComputerLocked(Snapshot args)4862         ComputerLocked(Snapshot args) {
4863             super(args);
4864             mLock = mService.mLock;
4865         }
4866 
resolveComponentName()4867         protected final ComponentName resolveComponentName() {
4868             return mService.mResolveComponentName;
4869         }
instantAppInstallerActivity()4870         protected final ActivityInfo instantAppInstallerActivity() {
4871             return mService.mInstantAppInstallerActivity;
4872         }
androidApplication()4873         protected final ApplicationInfo androidApplication() {
4874             return mService.mAndroidApplication;
4875         }
4876 
queryIntentServicesInternalBody(Intent intent, String resolvedType, int flags, int userId, int callingUid, String instantAppPkgName)4877         public final @NonNull List<ResolveInfo> queryIntentServicesInternalBody(Intent intent,
4878                 String resolvedType, int flags, int userId, int callingUid,
4879                 String instantAppPkgName) {
4880             synchronized (mLock) {
4881                 return super.queryIntentServicesInternalBody(intent, resolvedType, flags, userId,
4882                         callingUid, instantAppPkgName);
4883             }
4884         }
queryIntentActivitiesInternalBody( Intent intent, String resolvedType, int flags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits, String pkgName, String instantAppPkgName)4885         public final @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
4886                 Intent intent, String resolvedType, int flags, int filterCallingUid, int userId,
4887                 boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
4888                 String instantAppPkgName) {
4889             synchronized (mLock) {
4890                 return super.queryIntentActivitiesInternalBody(intent, resolvedType, flags,
4891                         filterCallingUid, userId, resolveForStart, allowDynamicSplits, pkgName,
4892                         instantAppPkgName);
4893             }
4894         }
getActivityInfoInternalBody(ComponentName component, int flags, int filterCallingUid, int userId)4895         public final ActivityInfo getActivityInfoInternalBody(ComponentName component, int flags,
4896                 int filterCallingUid, int userId) {
4897             synchronized (mLock) {
4898                 return super.getActivityInfoInternalBody(component, flags, filterCallingUid,
4899                         userId);
4900             }
4901         }
getPackage(String packageName)4902         public final AndroidPackage getPackage(String packageName) {
4903             synchronized (mLock) {
4904                 return super.getPackage(packageName);
4905             }
4906         }
getPackage(int uid)4907         public final AndroidPackage getPackage(int uid) {
4908             synchronized (mLock) {
4909                 return super.getPackage(uid);
4910             }
4911         }
getApplicationInfoInternalBody(String packageName, int flags, int filterCallingUid, int userId)4912         public final ApplicationInfo getApplicationInfoInternalBody(String packageName, int flags,
4913                 int filterCallingUid, int userId) {
4914             synchronized (mLock) {
4915                 return super.getApplicationInfoInternalBody(packageName, flags, filterCallingUid,
4916                         userId);
4917             }
4918         }
filterCandidatesWithDomainPreferredActivitiesLPrBody( Intent intent, int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, int userId, boolean debug)4919         public final ArrayList<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPrBody(
4920                 Intent intent, int matchFlags, List<ResolveInfo> candidates,
4921                 CrossProfileDomainInfo xpDomainInfo, int userId, boolean debug) {
4922             synchronized (mLock) {
4923                 return super.filterCandidatesWithDomainPreferredActivitiesLPrBody(intent,
4924                         matchFlags, candidates, xpDomainInfo, userId, debug);
4925             }
4926         }
getPackageInfoInternalBody(String packageName, long versionCode, int flags, int filterCallingUid, int userId)4927         public final PackageInfo getPackageInfoInternalBody(String packageName, long versionCode,
4928                 int flags, int filterCallingUid, int userId) {
4929             synchronized (mLock) {
4930                 return super.getPackageInfoInternalBody(packageName, versionCode, flags,
4931                         filterCallingUid, userId);
4932             }
4933         }
getPackageSettingInternal(String packageName, int callingUid)4934         public final PackageSetting getPackageSettingInternal(String packageName, int callingUid) {
4935             synchronized (mLock) {
4936                 return super.getPackageSettingInternal(packageName, callingUid);
4937             }
4938         }
getInstalledPackagesBody(int flags, int userId, int callingUid)4939         public final ParceledListSlice<PackageInfo> getInstalledPackagesBody(int flags, int userId,
4940                 int callingUid) {
4941             synchronized (mLock) {
4942                 return super.getInstalledPackagesBody(flags, userId, callingUid);
4943             }
4944         }
getServiceInfoBody(ComponentName component, int flags, int userId, int callingUid)4945         public final ServiceInfo getServiceInfoBody(ComponentName component, int flags, int userId,
4946                 int callingUid) {
4947             synchronized (mLock) {
4948                 return super.getServiceInfoBody(component, flags, userId, callingUid);
4949             }
4950         }
getInstantAppPackageName(int callingUid)4951         public final String getInstantAppPackageName(int callingUid) {
4952             synchronized (mLock) {
4953                 return super.getInstantAppPackageName(callingUid);
4954             }
4955         }
getPackagesForUidInternalBody(int callingUid, int userId, int appId, boolean isCallerInstantApp)4956         public final String[] getPackagesForUidInternalBody(int callingUid, int userId, int appId,
4957                 boolean isCallerInstantApp) {
4958             synchronized (mLock) {
4959                 return super.getPackagesForUidInternalBody(callingUid, userId, appId,
4960                         isCallerInstantApp);
4961             }
4962         }
isInstantAppInternalBody(String packageName, @UserIdInt int userId, int callingUid)4963         public final boolean isInstantAppInternalBody(String packageName, @UserIdInt int userId,
4964                 int callingUid) {
4965             synchronized (mLock) {
4966                 return super.isInstantAppInternalBody(packageName, userId, callingUid);
4967             }
4968         }
isInstantAppResolutionAllowedBody(Intent intent, List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck, int flags)4969         public final boolean isInstantAppResolutionAllowedBody(Intent intent,
4970                 List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck,
4971                 int flags) {
4972             synchronized (mLock) {
4973                 return super.isInstantAppResolutionAllowedBody(intent, resolvedActivities, userId,
4974                         skipPackageCheck, flags);
4975             }
4976         }
getPackageUidInternal(String packageName, int flags, int userId, int callingUid)4977         public final int getPackageUidInternal(String packageName, int flags, int userId,
4978                 int callingUid) {
4979             synchronized (mLock) {
4980                 return super.getPackageUidInternal(packageName, flags, userId, callingUid);
4981             }
4982         }
getSigningDetails(@onNull String packageName)4983         public final SigningDetails getSigningDetails(@NonNull String packageName) {
4984             synchronized (mLock) {
4985                 return super.getSigningDetails(packageName);
4986             }
4987         }
getSigningDetails(int uid)4988         public final SigningDetails getSigningDetails(int uid) {
4989             synchronized (mLock) {
4990                 return super.getSigningDetails(uid);
4991             }
4992         }
filterAppAccess(AndroidPackage pkg, int callingUid, int userId)4993         public final boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
4994             synchronized (mLock) {
4995                 return super.filterAppAccess(pkg, callingUid, userId);
4996             }
4997         }
filterAppAccess(String packageName, int callingUid, int userId)4998         public final boolean filterAppAccess(String packageName, int callingUid, int userId) {
4999             synchronized (mLock) {
5000                 return super.filterAppAccess(packageName, callingUid, userId);
5001             }
5002         }
dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState)5003         public final void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) {
5004             synchronized (mLock) {
5005                 super.dump(type, fd, pw, dumpState);
5006             }
5007         }
5008     }
5009 
5010     /**
5011      * This subclass delegates to methods in a Computer after reference-counting the computer.
5012      */
5013     private static class ComputerTracker implements Computer {
5014 
5015         // The number of times a thread reused a computer in its stack instead of fetching
5016         // a snapshot computer.
5017         private final AtomicInteger mReusedSnapshot = new AtomicInteger(0);
5018 
5019         // The number of times a thread reused a computer in its stack instead of fetching
5020         // a live computer.
5021         private final AtomicInteger mReusedLive = new AtomicInteger(0);
5022 
5023         private PackageManagerService mService;
ComputerTracker(PackageManagerService s)5024         ComputerTracker(PackageManagerService s) {
5025             mService = s;
5026         }
5027 
live()5028         private ThreadComputer live() {
5029             ThreadComputer current = mService.sThreadComputer.get();
5030             if (current.mRefCount > 0) {
5031                 current.acquire();
5032                 mReusedLive.incrementAndGet();
5033             } else {
5034                 current.acquire(mService.liveComputer());
5035             }
5036             return current;
5037         }
5038 
snapshot()5039         private ThreadComputer snapshot() {
5040             ThreadComputer current = mService.sThreadComputer.get();
5041             if (current.mRefCount > 0) {
5042                 current.acquire();
5043                 mReusedSnapshot.incrementAndGet();
5044             } else {
5045                 current.acquire(mService.snapshotComputer());
5046             }
5047             return current;
5048         }
5049 
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits)5050         public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
5051                 String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags,
5052                 int filterCallingUid, int userId, boolean resolveForStart,
5053                 boolean allowDynamicSplits) {
5054             ThreadComputer current = snapshot();
5055             try {
5056                 return current.mComputer.queryIntentActivitiesInternal(intent, resolvedType, flags,
5057                         privateResolveFlags, filterCallingUid, userId, resolveForStart,
5058                         allowDynamicSplits);
5059             } finally {
5060                 current.release();
5061             }
5062         }
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, int userId)5063         public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
5064                 String resolvedType, int flags, int userId) {
5065             ThreadComputer current = snapshot();
5066             try {
5067                 return current.mComputer.queryIntentActivitiesInternal(intent, resolvedType, flags,
5068                         userId);
5069             } finally {
5070                 current.release();
5071             }
5072         }
queryIntentServicesInternal(Intent intent, String resolvedType, int flags, int userId, int callingUid, boolean includeInstantApps)5073         public final @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
5074                 String resolvedType, int flags, int userId, int callingUid,
5075                 boolean includeInstantApps) {
5076             ThreadComputer current = snapshot();
5077             try {
5078                 return current.mComputer.queryIntentServicesInternal(intent, resolvedType, flags,
5079                         userId, callingUid, includeInstantApps);
5080             } finally {
5081                 current.release();
5082             }
5083         }
queryIntentActivitiesInternalBody( Intent intent, String resolvedType, int flags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits, String pkgName, String instantAppPkgName)5084         public final @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
5085                 Intent intent,
5086                 String resolvedType, int flags, int filterCallingUid, int userId,
5087                 boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
5088                 String instantAppPkgName) {
5089             ThreadComputer current = live();
5090             try {
5091                 return current.mComputer.queryIntentActivitiesInternalBody(intent, resolvedType,
5092                         flags, filterCallingUid, userId, resolveForStart, allowDynamicSplits,
5093                         pkgName, instantAppPkgName);
5094             } finally {
5095                 current.release();
5096             }
5097         }
getActivityInfo(ComponentName component, int flags, int userId)5098         public final ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
5099             ThreadComputer current = snapshot();
5100             try {
5101                 return current.mComputer.getActivityInfo(component, flags, userId);
5102             } finally {
5103                 current.release();
5104             }
5105         }
getActivityInfoInternal(ComponentName component, int flags, int filterCallingUid, int userId)5106         public final ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
5107                 int filterCallingUid, int userId) {
5108             ThreadComputer current = live();
5109             try {
5110                 return current.mComputer.getActivityInfoInternal(component, flags, filterCallingUid,
5111                         userId);
5112             } finally {
5113                 current.release();
5114             }
5115         }
getPackage(String packageName)5116         public final AndroidPackage getPackage(String packageName) {
5117             ThreadComputer current = snapshot();
5118             try {
5119                 return current.mComputer.getPackage(packageName);
5120             } finally {
5121                 current.release();
5122             }
5123         }
getPackage(int uid)5124         public final AndroidPackage getPackage(int uid) {
5125             ThreadComputer current = snapshot();
5126             try {
5127                 return current.mComputer.getPackage(uid);
5128             } finally {
5129                 current.release();
5130             }
5131         }
generateApplicationInfoFromSettingsLPw(String packageName, int flags, int filterCallingUid, int userId)5132         public final ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName,
5133                 int flags, int filterCallingUid, int userId) {
5134             ThreadComputer current = live();
5135             try {
5136                 return current.mComputer.generateApplicationInfoFromSettingsLPw(packageName, flags,
5137                         filterCallingUid, userId);
5138             } finally {
5139                 current.release();
5140             }
5141         }
getApplicationInfo(String packageName, int flags, int userId)5142         public final ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
5143             ThreadComputer current = snapshot();
5144             try {
5145                 return current.mComputer.getApplicationInfo(packageName, flags, userId);
5146             } finally {
5147                 current.release();
5148             }
5149         }
getApplicationInfoInternal(String packageName, int flags, int filterCallingUid, int userId)5150         public final ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
5151                 int filterCallingUid, int userId) {
5152             ThreadComputer current = live();
5153             try {
5154                 return current.mComputer.getApplicationInfoInternal(packageName, flags,
5155                         filterCallingUid, userId);
5156             } finally {
5157                 current.release();
5158             }
5159         }
getDefaultHomeActivity(int userId)5160         public final ComponentName getDefaultHomeActivity(int userId) {
5161             ThreadComputer current = live();
5162             try {
5163                 return current.mComputer.getDefaultHomeActivity(userId);
5164             } finally {
5165                 current.release();
5166             }
5167         }
getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId)5168         public final ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
5169                 int userId) {
5170             ThreadComputer current = live();
5171             try {
5172                 return current.mComputer.getHomeActivitiesAsUser(allHomeCandidates, userId);
5173             } finally {
5174                 current.release();
5175             }
5176         }
getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType, int flags, int sourceUserId, int parentUserId)5177         public final CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
5178                 String resolvedType, int flags, int sourceUserId, int parentUserId) {
5179             ThreadComputer current = live();
5180             try {
5181                 return current.mComputer.getCrossProfileDomainPreferredLpr(intent, resolvedType,
5182                         flags, sourceUserId, parentUserId);
5183             } finally {
5184                 current.release();
5185             }
5186         }
getHomeIntent()5187         public final Intent getHomeIntent() {
5188             ThreadComputer current = live();
5189             try {
5190                 return current.mComputer.getHomeIntent();
5191             } finally {
5192                 current.release();
5193             }
5194         }
getMatchingCrossProfileIntentFilters( Intent intent, String resolvedType, int userId)5195         public final List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(
5196                 Intent intent, String resolvedType, int userId) {
5197             ThreadComputer current = live();
5198             try {
5199                 return current.mComputer.getMatchingCrossProfileIntentFilters(intent, resolvedType,
5200                         userId);
5201             } finally {
5202                 current.release();
5203             }
5204         }
applyPostResolutionFilter( @onNull List<ResolveInfo> resolveInfos, String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, boolean resolveForStart, int userId, Intent intent)5205         public final List<ResolveInfo> applyPostResolutionFilter(
5206                 @NonNull List<ResolveInfo> resolveInfos,
5207                 String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
5208                 boolean resolveForStart, int userId, Intent intent) {
5209             ThreadComputer current = live();
5210             try {
5211                 return current.mComputer.applyPostResolutionFilter(resolveInfos, ephemeralPkgName,
5212                         allowDynamicSplits, filterCallingUid, resolveForStart, userId, intent);
5213             } finally {
5214                 current.release();
5215             }
5216         }
generatePackageInfo(PackageSetting ps, int flags, int userId)5217         public final PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
5218             ThreadComputer current = live();
5219             try {
5220                 return current.mComputer.generatePackageInfo(ps, flags, userId);
5221             } finally {
5222                 current.release();
5223             }
5224         }
getPackageInfo(String packageName, int flags, int userId)5225         public final PackageInfo getPackageInfo(String packageName, int flags, int userId) {
5226             ThreadComputer current = snapshot();
5227             try {
5228                 return current.mComputer.getPackageInfo(packageName, flags, userId);
5229             } finally {
5230                 current.release();
5231             }
5232         }
getPackageInfoInternal(String packageName, long versionCode, int flags, int filterCallingUid, int userId)5233         public final PackageInfo getPackageInfoInternal(String packageName, long versionCode,
5234                 int flags, int filterCallingUid, int userId) {
5235             ThreadComputer current = live();
5236             try {
5237                 return current.mComputer.getPackageInfoInternal(packageName, versionCode, flags,
5238                         filterCallingUid, userId);
5239             } finally {
5240                 current.release();
5241             }
5242         }
getPackageSetting(String packageName)5243         public final PackageSetting getPackageSetting(String packageName) {
5244             ThreadComputer current = snapshot();
5245             try {
5246                 return current.mComputer.getPackageSetting(packageName);
5247             } finally {
5248                 current.release();
5249             }
5250         }
getPackageSettingInternal(String packageName, int callingUid)5251         public final PackageSetting getPackageSettingInternal(String packageName, int callingUid) {
5252             ThreadComputer current = live();
5253             try {
5254                 return current.mComputer.getPackageSettingInternal(packageName, callingUid);
5255             } finally {
5256                 current.release();
5257             }
5258         }
getInstalledPackages(int flags, int userId)5259         public final ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
5260             ThreadComputer current = snapshot();
5261             try {
5262                 return current.mComputer.getInstalledPackages(flags, userId);
5263             } finally {
5264                 current.release();
5265             }
5266         }
createForwardingResolveInfoUnchecked(WatchedIntentFilter filter, int sourceUserId, int targetUserId)5267         public final ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
5268                 int sourceUserId, int targetUserId) {
5269             ThreadComputer current = live();
5270             try {
5271                 return current.mComputer.createForwardingResolveInfoUnchecked(filter, sourceUserId,
5272                         targetUserId);
5273             } finally {
5274                 current.release();
5275             }
5276         }
getServiceInfo(ComponentName component, int flags, int userId)5277         public final ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5278             ThreadComputer current = live();
5279             try {
5280                 return current.mComputer.getServiceInfo(component, flags, userId);
5281             } finally {
5282                 current.release();
5283             }
5284         }
getSharedLibraryInfoLPr(String name, long version)5285         public final SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version) {
5286             ThreadComputer current = live();
5287             try {
5288                 return current.mComputer.getSharedLibraryInfoLPr(name, version);
5289             } finally {
5290                 current.release();
5291             }
5292         }
getSigningDetails(@onNull String packageName)5293         public final SigningDetails getSigningDetails(@NonNull String packageName) {
5294             ThreadComputer current = snapshot();
5295             try {
5296                 return current.mComputer.getSigningDetails(packageName);
5297             } finally {
5298                 current.release();
5299             }
5300         }
getSigningDetails(int uid)5301         public final SigningDetails getSigningDetails(int uid) {
5302             ThreadComputer current = snapshot();
5303             try {
5304                 return current.mComputer.getSigningDetails(uid);
5305             } finally {
5306                 current.release();
5307             }
5308         }
getInstantAppPackageName(int callingUid)5309         public final String getInstantAppPackageName(int callingUid) {
5310             ThreadComputer current = snapshot();
5311             try {
5312                 return current.mComputer.getInstantAppPackageName(callingUid);
5313             } finally {
5314                 current.release();
5315             }
5316         }
resolveExternalPackageNameLPr(AndroidPackage pkg)5317         public final String resolveExternalPackageNameLPr(AndroidPackage pkg) {
5318             ThreadComputer current = live();
5319             try {
5320                 return current.mComputer.resolveExternalPackageNameLPr(pkg);
5321             } finally {
5322                 current.release();
5323             }
5324         }
resolveInternalPackageNameLPr(String packageName, long versionCode)5325         public final String resolveInternalPackageNameLPr(String packageName, long versionCode) {
5326             ThreadComputer current = live();
5327             try {
5328                 return current.mComputer.resolveInternalPackageNameLPr(packageName, versionCode);
5329             } finally {
5330                 current.release();
5331             }
5332         }
getPackagesForUid(int uid)5333         public final String[] getPackagesForUid(int uid) {
5334             ThreadComputer current = snapshot();
5335             try {
5336                 return current.mComputer.getPackagesForUid(uid);
5337             } finally {
5338                 current.release();
5339             }
5340         }
getProfileParent(int userId)5341         public final UserInfo getProfileParent(int userId) {
5342             ThreadComputer current = live();
5343             try {
5344                 return current.mComputer.getProfileParent(userId);
5345             } finally {
5346                 current.release();
5347             }
5348         }
canViewInstantApps(int callingUid, int userId)5349         public final boolean canViewInstantApps(int callingUid, int userId) {
5350             ThreadComputer current = live();
5351             try {
5352                 return current.mComputer.canViewInstantApps(callingUid, userId);
5353             } finally {
5354                 current.release();
5355             }
5356         }
filterAppAccess(AndroidPackage pkg, int callingUid, int userId)5357         public final boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
5358             ThreadComputer current = snapshot();
5359             try {
5360                 return current.mComputer.filterAppAccess(pkg, callingUid, userId);
5361             } finally {
5362                 current.release();
5363             }
5364         }
filterAppAccess(String packageName, int callingUid, int userId)5365         public final boolean filterAppAccess(String packageName, int callingUid, int userId) {
5366             ThreadComputer current = snapshot();
5367             try {
5368                 return current.mComputer.filterAppAccess(packageName, callingUid, userId);
5369             } finally {
5370                 current.release();
5371             }
5372         }
filterSharedLibPackageLPr(@ullable PackageSetting ps, int uid, int userId, int flags)5373         public final boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid,
5374                 int userId, int flags) {
5375             ThreadComputer current = live();
5376             try {
5377                 return current.mComputer.filterSharedLibPackageLPr(ps, uid, userId, flags);
5378             } finally {
5379                 current.release();
5380             }
5381         }
isCallerSameApp(String packageName, int uid)5382         public final boolean isCallerSameApp(String packageName, int uid) {
5383             ThreadComputer current = live();
5384             try {
5385                 return current.mComputer.isCallerSameApp(packageName, uid);
5386             } finally {
5387                 current.release();
5388             }
5389         }
isComponentVisibleToInstantApp(@ullable ComponentName component)5390         public final boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
5391             ThreadComputer current = live();
5392             try {
5393                 return current.mComputer.isComponentVisibleToInstantApp(component);
5394             } finally {
5395                 current.release();
5396             }
5397         }
isComponentVisibleToInstantApp(@ullable ComponentName component, @ComponentType int type)5398         public final boolean isComponentVisibleToInstantApp(@Nullable ComponentName component,
5399                 @ComponentType int type) {
5400             ThreadComputer current = live();
5401             try {
5402                 return current.mComputer.isComponentVisibleToInstantApp(component, type);
5403             } finally {
5404                 current.release();
5405             }
5406         }
isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId, String resolvedType, int flags)5407         public final boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent,
5408                 int userId, String resolvedType, int flags) {
5409             ThreadComputer current = live();
5410             try {
5411                 return current.mComputer.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent,
5412                         userId, resolvedType, flags);
5413             } finally {
5414                 current.release();
5415             }
5416         }
isInstantApp(String packageName, int userId)5417         public final boolean isInstantApp(String packageName, int userId) {
5418             ThreadComputer current = snapshot();
5419             try {
5420                 return current.mComputer.isInstantApp(packageName, userId);
5421             } finally {
5422                 current.release();
5423             }
5424         }
isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid)5425         public final boolean isInstantAppInternal(String packageName, @UserIdInt int userId,
5426                 int callingUid) {
5427             ThreadComputer current = live();
5428             try {
5429                 return current.mComputer.isInstantAppInternal(packageName, userId, callingUid);
5430             } finally {
5431                 current.release();
5432             }
5433         }
isSameProfileGroup(@serIdInt int callerUserId, @UserIdInt int userId)5434         public final boolean isSameProfileGroup(@UserIdInt int callerUserId,
5435                 @UserIdInt int userId) {
5436             ThreadComputer current = live();
5437             try {
5438                 return current.mComputer.isSameProfileGroup(callerUserId, userId);
5439             } finally {
5440                 current.release();
5441             }
5442         }
shouldFilterApplicationLocked(@onNull SharedUserSetting sus, int callingUid, int userId)5443         public final boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus,
5444                 int callingUid, int userId) {
5445             ThreadComputer current = live();
5446             try {
5447                 return current.mComputer.shouldFilterApplicationLocked(sus, callingUid, userId);
5448             } finally {
5449                 current.release();
5450             }
5451         }
shouldFilterApplicationLocked(@ullable PackageSetting ps, int callingUid, @Nullable ComponentName component, @ComponentType int componentType, int userId)5452         public final boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps,
5453                 int callingUid,
5454                 @Nullable ComponentName component, @ComponentType int componentType, int userId) {
5455             ThreadComputer current = live();
5456             try {
5457                 return current.mComputer.shouldFilterApplicationLocked(ps, callingUid, component,
5458                         componentType, userId);
5459             } finally {
5460                 current.release();
5461             }
5462         }
shouldFilterApplicationLocked(@ullable PackageSetting ps, int callingUid, int userId)5463         public final boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps,
5464                 int callingUid, int userId) {
5465             ThreadComputer current = live();
5466             try {
5467                 return current.mComputer.shouldFilterApplicationLocked(ps, callingUid, userId);
5468             } finally {
5469                 current.release();
5470             }
5471         }
checkUidPermission(String permName, int uid)5472         public final int checkUidPermission(String permName, int uid) {
5473             ThreadComputer current = snapshot();
5474             try {
5475                 return current.mComputer.checkUidPermission(permName, uid);
5476             } finally {
5477                 current.release();
5478             }
5479         }
getPackageUidInternal(String packageName, int flags, int userId, int callingUid)5480         public final int getPackageUidInternal(String packageName, int flags, int userId,
5481                 int callingUid) {
5482             ThreadComputer current = live();
5483             try {
5484                 return current.mComputer.getPackageUidInternal(packageName, flags, userId,
5485                         callingUid);
5486             } finally {
5487                 current.release();
5488             }
5489         }
updateFlagsForApplication(int flags, int userId)5490         public final int updateFlagsForApplication(int flags, int userId) {
5491             ThreadComputer current = live();
5492             try {
5493                 return current.mComputer.updateFlagsForApplication(flags, userId);
5494             } finally {
5495                 current.release();
5496             }
5497         }
updateFlagsForComponent(int flags, int userId)5498         public final int updateFlagsForComponent(int flags, int userId) {
5499             ThreadComputer current = live();
5500             try {
5501                 return current.mComputer.updateFlagsForComponent(flags, userId);
5502             } finally {
5503                 current.release();
5504             }
5505         }
updateFlagsForPackage(int flags, int userId)5506         public final int updateFlagsForPackage(int flags, int userId) {
5507             ThreadComputer current = live();
5508             try {
5509                 return current.mComputer.updateFlagsForPackage(flags, userId);
5510             } finally {
5511                 current.release();
5512             }
5513         }
updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc)5514         public final int updateFlagsForResolve(int flags, int userId, int callingUid,
5515                 boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
5516             ThreadComputer current = live();
5517             try {
5518                 return current.mComputer.updateFlagsForResolve(flags, userId, callingUid,
5519                         wantInstantApps, isImplicitImageCaptureIntentAndNotSetByDpc);
5520             } finally {
5521                 current.release();
5522             }
5523         }
updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc)5524         public final int updateFlagsForResolve(int flags, int userId, int callingUid,
5525                 boolean wantInstantApps, boolean onlyExposedExplicitly,
5526                 boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
5527             ThreadComputer current = live();
5528             try {
5529                 return current.mComputer.updateFlagsForResolve(flags, userId, callingUid,
5530                         wantInstantApps, onlyExposedExplicitly,
5531                         isImplicitImageCaptureIntentAndNotSetByDpc);
5532             } finally {
5533                 current.release();
5534             }
5535         }
dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState)5536         public final void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) {
5537             ThreadComputer current = live();
5538             try {
5539                 current.mComputer.dump(type, fd, pw, dumpState);
5540             } finally {
5541                 current.release();
5542             }
5543         }
enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message)5544         public final void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
5545                 boolean requireFullPermission, boolean checkShell, String message) {
5546             ThreadComputer current = live();
5547             try {
5548                 current.mComputer.enforceCrossUserOrProfilePermission(callingUid, userId,
5549                         requireFullPermission, checkShell, message);
5550             } finally {
5551                 current.release();
5552             }
5553         }
enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message)5554         public final void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
5555                 boolean requireFullPermission, boolean checkShell, String message) {
5556             ThreadComputer current = live();
5557             try {
5558                 current.mComputer.enforceCrossUserPermission(callingUid, userId,
5559                         requireFullPermission, checkShell, message);
5560             } finally {
5561                 current.release();
5562             }
5563         }
enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, String message)5564         public final void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
5565                 boolean requireFullPermission, boolean checkShell,
5566                 boolean requirePermissionWhenSameUser, String message) {
5567             ThreadComputer current = live();
5568             try {
5569                 current.mComputer.enforceCrossUserPermission(callingUid, userId,
5570                         requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
5571             } finally {
5572                 current.release();
5573             }
5574         }
5575     }
5576 
5577 
5578     // Compute read-only functions, based on live data.  This attribute may be modified multiple
5579     // times during the PackageManagerService constructor but it should not be modified thereafter.
5580     private ComputerLocked mLiveComputer;
5581 
5582     // A lock-free cache for frequently called functions.
5583     private volatile Computer mSnapshotComputer;
5584 
5585     // A trampoline that directs callers to either the live or snapshot computer.
5586     private final ComputerTracker mComputer = new ComputerTracker(this);
5587 
5588     // If true, the snapshot is invalid (stale).  The attribute is static since it may be
5589     // set from outside classes.  The attribute may be set to true anywhere, although it
5590     // should only be set true while holding mLock.  However, the attribute id guaranteed
5591     // to be set false only while mLock and mSnapshotLock are both held.
5592     private static AtomicBoolean sSnapshotInvalid = new AtomicBoolean(true);
5593     // The package manager that is using snapshots.
5594     private static PackageManagerService sSnapshotConsumer = null;
5595     // If true, the snapshot is corked.  Do not create a new snapshot but use the live
5596     // computer.  This throttles snapshot creation during periods of churn in Package
5597     // Manager.
5598     private static AtomicInteger sSnapshotCorked = new AtomicInteger(0);
5599 
5600     /**
5601      * This class records the Computer being used by a thread and the Computer's reference
5602      * count.  There is a thread-local copy of this class.
5603      */
5604     private static class ThreadComputer {
5605         Computer mComputer = null;
5606         int mRefCount = 0;
acquire(Computer c)5607         void acquire(Computer c) {
5608             if (mRefCount != 0 && mComputer != c) {
5609                 throw new RuntimeException("computer mismatch, count = " + mRefCount);
5610             }
5611             mComputer = c;
5612             mRefCount++;
5613         }
acquire()5614         void acquire() {
5615             if (mRefCount == 0 || mComputer == null) {
5616                 throw new RuntimeException("computer acquire on empty ref count");
5617             }
5618             mRefCount++;
5619         }
release()5620         void release() {
5621             if (--mRefCount == 0) {
5622                 mComputer = null;
5623             }
5624         }
5625     }
5626     private static ThreadLocal<ThreadComputer> sThreadComputer = new ThreadLocal<>() {
5627             @Override protected ThreadComputer initialValue() {
5628                 return new ThreadComputer();
5629             }};
5630 
5631     /**
5632      * This lock is used to make reads from {@link #sSnapshotInvalid} and
5633      * {@link #mSnapshotComputer} atomic inside {@code snapshotComputer()}.  This lock is
5634      * not meant to be used outside that method.  This lock must be taken before
5635      * {@link #mLock} is taken.
5636      */
5637     private final Object mSnapshotLock = new Object();
5638 
5639     /**
5640      * The snapshot statistics.  These are collected to track performance and to identify
5641      * situations in which the snapshots are misbehaving.
5642      */
5643     private final SnapshotStatistics mSnapshotStatistics;
5644 
5645     // The snapshot disable/enable switch.  An image with the flag set true uses snapshots
5646     // and an image with the flag set false does not use snapshots.
5647     private static final boolean SNAPSHOT_ENABLED = true;
5648 
5649     // The default auto-cork delay for snapshots.  This is 1s.
5650     private static final long SNAPSHOT_AUTOCORK_DELAY_MS = TimeUnit.SECONDS.toMillis(1);
5651 
5652     // The per-instance snapshot disable/enable flag.  This is generally set to false in
5653     // test instances and set to SNAPSHOT_ENABLED in operational instances.
5654     private final boolean mSnapshotEnabled;
5655 
5656     /**
5657      * Return the live computer.
5658      */
liveComputer()5659     private Computer liveComputer() {
5660         return mLiveComputer;
5661     }
5662 
5663     /**
5664      * Return the cached computer.  The method will rebuild the cached computer if necessary.
5665      * The live computer will be returned if snapshots are disabled.
5666      */
snapshotComputer()5667     private Computer snapshotComputer() {
5668         if (!mSnapshotEnabled) {
5669             return mLiveComputer;
5670         }
5671         if (Thread.holdsLock(mLock)) {
5672             // If the current thread holds mLock then it may have modified state but not
5673             // yet invalidated the snapshot.  Always give the thread the live computer.
5674             return mLiveComputer;
5675         } else if (sSnapshotCorked.get() > 0) {
5676             // Snapshots are corked, which means new ones should not be built right now.
5677             mSnapshotStatistics.corked();
5678             return mLiveComputer;
5679         }
5680         synchronized (mSnapshotLock) {
5681             // This synchronization block serializes access to the snapshot computer and
5682             // to the code that samples mSnapshotInvalid.
5683             Computer c = mSnapshotComputer;
5684             if (sSnapshotInvalid.getAndSet(false) || (c == null)) {
5685                 // The snapshot is invalid if it is marked as invalid or if it is null.  If it
5686                 // is null, then it is currently being rebuilt by rebuildSnapshot().
5687                 synchronized (mLock) {
5688                     // Rebuild the snapshot if it is invalid.  Note that the snapshot might be
5689                     // invalidated as it is rebuilt.  However, the snapshot is still
5690                     // self-consistent (the lock is being held) and is current as of the time
5691                     // this function is entered.
5692                     rebuildSnapshot();
5693 
5694                     // Guaranteed to be non-null.  mSnapshotComputer is only be set to null
5695                     // temporarily in rebuildSnapshot(), which is guarded by mLock().  Since
5696                     // the mLock is held in this block and since rebuildSnapshot() is
5697                     // complete, the attribute can not now be null.
5698                     c = mSnapshotComputer;
5699                 }
5700             }
5701             c.use();
5702             return c;
5703         }
5704     }
5705 
5706     /**
5707      * Rebuild the cached computer.  mSnapshotComputer is temporarily set to null to block other
5708      * threads from using the invalid computer until it is rebuilt.
5709      */
5710     @GuardedBy({ "mLock", "mSnapshotLock"})
rebuildSnapshot()5711     private void rebuildSnapshot() {
5712         final long now = SystemClock.currentTimeMicro();
5713         final int hits = mSnapshotComputer == null ? -1 : mSnapshotComputer.getUsed();
5714         mSnapshotComputer = null;
5715         final Snapshot args = new Snapshot(Snapshot.SNAPPED);
5716         mSnapshotComputer = new ComputerEngine(args);
5717         final long done = SystemClock.currentTimeMicro();
5718 
5719         mSnapshotStatistics.rebuild(now, done, hits);
5720     }
5721 
5722     /**
5723      * Create a new snapshot.  Used for testing only.  This does collect statistics or
5724      * update the snapshot used by other actors.  It does not alter the invalidation
5725      * flag.  This method takes the mLock internally.
5726      */
createNewSnapshot()5727     private Computer createNewSnapshot() {
5728         synchronized (mLock) {
5729             final Snapshot args = new Snapshot(Snapshot.SNAPPED);
5730             return new ComputerEngine(args);
5731         }
5732     }
5733 
5734     /**
5735      * Cork snapshots.  This times out after the programmed delay.
5736      */
corkSnapshots(int multiplier)5737     private void corkSnapshots(int multiplier) {
5738         int corking = sSnapshotCorked.getAndIncrement();
5739         if (TRACE_SNAPSHOTS && corking == 0) {
5740             Log.i(TAG, "snapshot: corking goes positive");
5741         }
5742         Message message = mHandler.obtainMessage(SNAPSHOT_UNCORK);
5743         mHandler.sendMessageDelayed(message, SNAPSHOT_AUTOCORK_DELAY_MS * multiplier);
5744     }
5745 
5746     /**
5747      * Create a live computer
5748      */
createLiveComputer()5749     private ComputerLocked createLiveComputer() {
5750         return new ComputerLocked(new Snapshot(Snapshot.LIVE));
5751     }
5752 
5753     /**
5754      * This method is called when the state of PackageManagerService changes so as to
5755      * invalidate the current snapshot.
5756      * @param what The {@link Watchable} that reported the change
5757      * @hide
5758      */
onChange(@ullable Watchable what)5759     public static void onChange(@Nullable Watchable what) {
5760         if (TRACE_SNAPSHOTS) {
5761             Log.i(TAG, "snapshot: onChange(" + what + ")");
5762         }
5763         sSnapshotInvalid.set(true);
5764     }
5765 
5766     /**
5767      * Report a locally-detected change to observers.  The <what> parameter is left null,
5768      * but it signifies that the change was detected by PackageManagerService itself.
5769      */
onChanged()5770     private static void onChanged() {
5771         onChange(null);
5772     }
5773 
5774     class PackageHandler extends Handler {
5775 
PackageHandler(Looper looper)5776         PackageHandler(Looper looper) {
5777             super(looper);
5778         }
5779 
handleMessage(Message msg)5780         public void handleMessage(Message msg) {
5781             try {
5782                 doHandleMessage(msg);
5783             } finally {
5784                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
5785             }
5786         }
5787 
doHandleMessage(Message msg)5788         void doHandleMessage(Message msg) {
5789             switch (msg.what) {
5790                 case INIT_COPY: {
5791                     HandlerParams params = (HandlerParams) msg.obj;
5792                     if (params != null) {
5793                         if (DEBUG_INSTALL) Slog.i(TAG, "init_copy: " + params);
5794                         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
5795                                 System.identityHashCode(params));
5796                         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
5797                         params.startCopy();
5798                         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5799                     }
5800                     break;
5801                 }
5802                 case SEND_PENDING_BROADCAST: {
5803                     String packages[];
5804                     ArrayList<String> components[];
5805                     int size = 0;
5806                     int uids[];
5807                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
5808                     synchronized (mLock) {
5809                         size = mPendingBroadcasts.size();
5810                         if (size <= 0) {
5811                             // Nothing to be done. Just return
5812                             return;
5813                         }
5814                         packages = new String[size];
5815                         components = new ArrayList[size];
5816                         uids = new int[size];
5817                         int i = 0;  // filling out the above arrays
5818 
5819                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
5820                             final int packageUserId = mPendingBroadcasts.userIdAt(n);
5821                             final ArrayMap<String, ArrayList<String>> componentsToBroadcast =
5822                                     mPendingBroadcasts.packagesForUserId(packageUserId);
5823                             final int numComponents = componentsToBroadcast.size();
5824                             for (int index = 0; i < size && index < numComponents; index++) {
5825                                 packages[i] = componentsToBroadcast.keyAt(index);
5826                                 components[i] = componentsToBroadcast.valueAt(index);
5827                                 final PackageSetting ps = mSettings.getPackageLPr(packages[i]);
5828                                 uids[i] = (ps != null)
5829                                         ? UserHandle.getUid(packageUserId, ps.appId)
5830                                         : -1;
5831                                 i++;
5832                             }
5833                         }
5834                         size = i;
5835                         mPendingBroadcasts.clear();
5836                     }
5837                     // Send broadcasts
5838                     for (int i = 0; i < size; i++) {
5839                         sendPackageChangedBroadcast(packages[i], true /* dontKillApp */,
5840                                 components[i], uids[i], null /* reason */);
5841                     }
5842                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
5843                     break;
5844                 }
5845                 case POST_INSTALL: {
5846                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
5847 
5848                     PostInstallData data = mRunningInstalls.get(msg.arg1);
5849                     final boolean didRestore = (msg.arg2 != 0);
5850                     mRunningInstalls.delete(msg.arg1);
5851 
5852                     if (data != null && data.res.freezer != null) {
5853                         data.res.freezer.close();
5854                     }
5855 
5856                     if (data != null && data.mPostInstallRunnable != null) {
5857                         data.mPostInstallRunnable.run();
5858                     } else if (data != null && data.args != null) {
5859                         InstallArgs args = data.args;
5860                         PackageInstalledInfo parentRes = data.res;
5861 
5862                         final boolean killApp = (args.installFlags
5863                                 & PackageManager.INSTALL_DONT_KILL_APP) == 0;
5864                         final boolean virtualPreload = ((args.installFlags
5865                                 & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
5866 
5867                         handlePackagePostInstall(parentRes, killApp, virtualPreload,
5868                                 didRestore, args.installSource.installerPackageName, args.observer,
5869                                 args.mDataLoaderType);
5870 
5871                         // Log tracing if needed
5872                         if (args.traceMethod != null) {
5873                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
5874                                     args.traceCookie);
5875                         }
5876                     } else if (DEBUG_INSTALL) {
5877                         // No post-install when we run restore from installExistingPackageForUser
5878                         Slog.i(TAG, "Nothing to do for post-install token " + msg.arg1);
5879                     }
5880 
5881                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
5882                 } break;
5883                 case DEFERRED_NO_KILL_POST_DELETE: {
5884                     synchronized (mInstallLock) {
5885                         InstallArgs args = (InstallArgs) msg.obj;
5886                         if (args != null) {
5887                             args.doPostDeleteLI(true);
5888                         }
5889                     }
5890                 } break;
5891                 case DEFERRED_NO_KILL_INSTALL_OBSERVER: {
5892                     String packageName = (String) msg.obj;
5893                     if (packageName != null) {
5894                         notifyInstallObserver(packageName);
5895                     }
5896                 } break;
5897                 case WRITE_SETTINGS: {
5898                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
5899                     synchronized (mLock) {
5900                         removeMessages(WRITE_SETTINGS);
5901                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
5902                         writeSettingsLPrTEMP();
5903                         mDirtyUsers.clear();
5904                     }
5905                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
5906                 } break;
5907                 case WRITE_PACKAGE_RESTRICTIONS: {
5908                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
5909                     synchronized (mLock) {
5910                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
5911                         for (int userId : mDirtyUsers) {
5912                             mSettings.writePackageRestrictionsLPr(userId);
5913                         }
5914                         mDirtyUsers.clear();
5915                     }
5916                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
5917                 } break;
5918                 case WRITE_PACKAGE_LIST: {
5919                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
5920                     synchronized (mLock) {
5921                         removeMessages(WRITE_PACKAGE_LIST);
5922                         mSettings.writePackageListLPr(msg.arg1);
5923                     }
5924                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
5925                 } break;
5926                 case CHECK_PENDING_VERIFICATION: {
5927                     final int verificationId = msg.arg1;
5928                     final PackageVerificationState state = mPendingVerification.get(verificationId);
5929 
5930                     if ((state != null) && !state.isVerificationComplete()
5931                             && !state.timeoutExtended()) {
5932                         final VerificationParams params = state.getVerificationParams();
5933                         final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
5934 
5935                         Slog.i(TAG, "Verification timed out for " + originUri);
5936 
5937                         final UserHandle user = params.getUser();
5938                         if (getDefaultVerificationResponse(user)
5939                                 == PackageManager.VERIFICATION_ALLOW) {
5940                             Slog.i(TAG, "Continuing with installation of " + originUri);
5941                             state.setVerifierResponse(Binder.getCallingUid(),
5942                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
5943                             broadcastPackageVerified(verificationId, originUri,
5944                                     PackageManager.VERIFICATION_ALLOW, null, params.mDataLoaderType,
5945                                     user);
5946                         } else {
5947                             broadcastPackageVerified(verificationId, originUri,
5948                                     PackageManager.VERIFICATION_REJECT, null,
5949                                     params.mDataLoaderType, user);
5950                             params.setReturnCode(
5951                                     PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
5952                             state.setVerifierResponse(Binder.getCallingUid(),
5953                                     PackageManager.VERIFICATION_REJECT);
5954                         }
5955 
5956                         if (state.areAllVerificationsComplete()) {
5957                             mPendingVerification.remove(verificationId);
5958                         }
5959 
5960                         Trace.asyncTraceEnd(
5961                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
5962 
5963                         params.handleVerificationFinished();
5964 
5965                     }
5966                     break;
5967                 }
5968                 case CHECK_PENDING_INTEGRITY_VERIFICATION: {
5969                     final int verificationId = msg.arg1;
5970                     final PackageVerificationState state = mPendingVerification.get(verificationId);
5971 
5972                     if (state != null && !state.isIntegrityVerificationComplete()) {
5973                         final VerificationParams params = state.getVerificationParams();
5974                         final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
5975 
5976                         Slog.i(TAG, "Integrity verification timed out for " + originUri);
5977 
5978                         state.setIntegrityVerificationResult(
5979                                 getDefaultIntegrityVerificationResponse());
5980 
5981                         if (getDefaultIntegrityVerificationResponse()
5982                                 == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) {
5983                             Slog.i(TAG, "Integrity check times out, continuing with " + originUri);
5984                         } else {
5985                             params.setReturnCode(
5986                                     PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
5987                         }
5988 
5989                         if (state.areAllVerificationsComplete()) {
5990                             mPendingVerification.remove(verificationId);
5991                         }
5992 
5993                         Trace.asyncTraceEnd(
5994                                 TRACE_TAG_PACKAGE_MANAGER,
5995                                 "integrity_verification",
5996                                 verificationId);
5997 
5998                         params.handleIntegrityVerificationFinished();
5999                     }
6000                     break;
6001                 }
6002                 case PACKAGE_VERIFIED: {
6003                     final int verificationId = msg.arg1;
6004 
6005                     final PackageVerificationState state = mPendingVerification.get(verificationId);
6006                     if (state == null) {
6007                         Slog.w(TAG, "Verification with id " + verificationId
6008                                 + " not found."
6009                                 + " It may be invalid or overridden by integrity verification");
6010                         break;
6011                     }
6012 
6013                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
6014 
6015                     state.setVerifierResponse(response.callerUid, response.code);
6016 
6017                     if (state.isVerificationComplete()) {
6018                         final VerificationParams params = state.getVerificationParams();
6019                         final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
6020 
6021                         if (state.isInstallAllowed()) {
6022                             broadcastPackageVerified(verificationId, originUri,
6023                                     response.code, null, params.mDataLoaderType, params.getUser());
6024                         } else {
6025                             params.setReturnCode(
6026                                     PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
6027                         }
6028 
6029                         if (state.areAllVerificationsComplete()) {
6030                             mPendingVerification.remove(verificationId);
6031                         }
6032 
6033                         Trace.asyncTraceEnd(
6034                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
6035 
6036                         params.handleVerificationFinished();
6037                     }
6038 
6039                     break;
6040                 }
6041                 case INTEGRITY_VERIFICATION_COMPLETE: {
6042                     final int verificationId = msg.arg1;
6043 
6044                     final PackageVerificationState state = mPendingVerification.get(verificationId);
6045                     if (state == null) {
6046                         Slog.w(TAG, "Integrity verification with id " + verificationId
6047                                 + " not found. It may be invalid or overridden by verifier");
6048                         break;
6049                     }
6050 
6051                     final int response = (Integer) msg.obj;
6052                     final VerificationParams params = state.getVerificationParams();
6053                     final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
6054 
6055                     state.setIntegrityVerificationResult(response);
6056 
6057                     if (response == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) {
6058                         Slog.i(TAG, "Integrity check passed for " + originUri);
6059                     } else {
6060                         params.setReturnCode(
6061                                 PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
6062                     }
6063 
6064                     if (state.areAllVerificationsComplete()) {
6065                         mPendingVerification.remove(verificationId);
6066                     }
6067 
6068                     Trace.asyncTraceEnd(
6069                             TRACE_TAG_PACKAGE_MANAGER,
6070                             "integrity_verification",
6071                             verificationId);
6072 
6073                     params.handleIntegrityVerificationFinished();
6074                     break;
6075                 }
6076                 case INSTANT_APP_RESOLUTION_PHASE_TWO: {
6077                     InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
6078                             mInstantAppResolverConnection,
6079                             (InstantAppRequest) msg.obj,
6080                             mInstantAppInstallerActivity,
6081                             mHandler);
6082                     break;
6083                 }
6084                 case ENABLE_ROLLBACK_STATUS: {
6085                     final int enableRollbackToken = msg.arg1;
6086                     final int enableRollbackCode = msg.arg2;
6087                     final VerificationParams params =
6088                             mPendingEnableRollback.get(enableRollbackToken);
6089                     if (params == null) {
6090                         Slog.w(TAG, "Invalid rollback enabled token "
6091                                 + enableRollbackToken + " received");
6092                         break;
6093                     }
6094 
6095                     mPendingEnableRollback.remove(enableRollbackToken);
6096 
6097                     if (enableRollbackCode != PackageManagerInternal.ENABLE_ROLLBACK_SUCCEEDED) {
6098                         final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
6099                         Slog.w(TAG, "Failed to enable rollback for " + originUri);
6100                         Slog.w(TAG, "Continuing with installation of " + originUri);
6101                     }
6102 
6103                     Trace.asyncTraceEnd(
6104                             TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
6105 
6106                     params.handleRollbackEnabled();
6107                     break;
6108                 }
6109                 case ENABLE_ROLLBACK_TIMEOUT: {
6110                     final int enableRollbackToken = msg.arg1;
6111                     final int sessionId = msg.arg2;
6112                     final VerificationParams params =
6113                             mPendingEnableRollback.get(enableRollbackToken);
6114                     if (params != null) {
6115                         final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
6116 
6117                         Slog.w(TAG, "Enable rollback timed out for " + originUri);
6118                         mPendingEnableRollback.remove(enableRollbackToken);
6119 
6120                         Slog.w(TAG, "Continuing with installation of " + originUri);
6121                         Trace.asyncTraceEnd(
6122                                 TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
6123                         params.handleRollbackEnabled();
6124                         Intent rollbackTimeoutIntent = new Intent(
6125                                 Intent.ACTION_CANCEL_ENABLE_ROLLBACK);
6126                         rollbackTimeoutIntent.putExtra(
6127                                 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_SESSION_ID,
6128                                 sessionId);
6129                         rollbackTimeoutIntent.addFlags(
6130                                 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
6131                         mContext.sendBroadcastAsUser(rollbackTimeoutIntent, UserHandle.SYSTEM,
6132                                 android.Manifest.permission.PACKAGE_ROLLBACK_AGENT);
6133                     }
6134                     break;
6135                 }
6136                 case DOMAIN_VERIFICATION: {
6137                     int messageCode = msg.arg1;
6138                     Object object = msg.obj;
6139                     mDomainVerificationManager.runMessage(messageCode, object);
6140                     break;
6141                 }
6142                 case SNAPSHOT_UNCORK: {
6143                     int corking = sSnapshotCorked.decrementAndGet();
6144                     if (TRACE_SNAPSHOTS && corking == 0) {
6145                         Log.e(TAG, "snapshot: corking goes to zero in message handler");
6146                     }
6147                     break;
6148                 }
6149             }
6150         }
6151     }
6152 
handlePackagePostInstall(PackageInstalledInfo res, boolean killApp, boolean virtualPreload, boolean launchedForRestore, String installerPackage, IPackageInstallObserver2 installObserver, int dataLoaderType)6153     private void handlePackagePostInstall(PackageInstalledInfo res, boolean killApp,
6154             boolean virtualPreload, boolean launchedForRestore, String installerPackage,
6155             IPackageInstallObserver2 installObserver, int dataLoaderType) {
6156         boolean succeeded = res.returnCode == PackageManager.INSTALL_SUCCEEDED;
6157         final boolean update = res.removedInfo != null && res.removedInfo.removedPackage != null;
6158         final String packageName = res.name;
6159         final PackageSetting pkgSetting = succeeded ? getPackageSetting(packageName) : null;
6160         final boolean removedBeforeUpdate = (pkgSetting == null)
6161                 || (pkgSetting.isSystem() && !pkgSetting.getPathString().equals(res.pkg.getPath()));
6162         if (succeeded && removedBeforeUpdate) {
6163             Slog.e(TAG, packageName + " was removed before handlePackagePostInstall "
6164                     + "could be executed");
6165             res.returnCode = INSTALL_FAILED_PACKAGE_CHANGED;
6166             res.returnMsg = "Package was removed before install could complete.";
6167 
6168             // Remove the update failed package's older resources safely now
6169             InstallArgs args = res.removedInfo != null ? res.removedInfo.args : null;
6170             if (args != null) {
6171                 synchronized (mInstallLock) {
6172                     args.doPostDeleteLI(true);
6173                 }
6174             }
6175             notifyInstallObserver(res, installObserver);
6176             return;
6177         }
6178 
6179         if (succeeded) {
6180             // Clear the uid cache after we installed a new package.
6181             mPerUidReadTimeoutsCache = null;
6182 
6183             // Send the removed broadcasts
6184             if (res.removedInfo != null) {
6185                 res.removedInfo.sendPackageRemovedBroadcasts(killApp, false /*removedBySystem*/);
6186             }
6187 
6188             final String installerPackageName =
6189                     res.installerPackageName != null
6190                             ? res.installerPackageName
6191                             : res.removedInfo != null
6192                                     ? res.removedInfo.installerPackageName
6193                                     : null;
6194 
6195             synchronized (mLock) {
6196                 mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
6197             }
6198 
6199             // Determine the set of users who are adding this package for
6200             // the first time vs. those who are seeing an update.
6201             int[] firstUserIds = EMPTY_INT_ARRAY;
6202             int[] firstInstantUserIds = EMPTY_INT_ARRAY;
6203             int[] updateUserIds = EMPTY_INT_ARRAY;
6204             int[] instantUserIds = EMPTY_INT_ARRAY;
6205             final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
6206             final PackageSetting ps = pkgSetting;
6207             for (int newUser : res.newUsers) {
6208                 final boolean isInstantApp = ps.getInstantApp(newUser);
6209                 if (allNewUsers) {
6210                     if (isInstantApp) {
6211                         firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
6212                     } else {
6213                         firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
6214                     }
6215                     continue;
6216                 }
6217                 boolean isNew = true;
6218                 for (int origUser : res.origUsers) {
6219                     if (origUser == newUser) {
6220                         isNew = false;
6221                         break;
6222                     }
6223                 }
6224                 if (isNew) {
6225                     if (isInstantApp) {
6226                         firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
6227                     } else {
6228                         firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
6229                     }
6230                 } else {
6231                     if (isInstantApp) {
6232                         instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
6233                     } else {
6234                         updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
6235                     }
6236                 }
6237             }
6238 
6239             // Send installed broadcasts if the package is not a static shared lib.
6240             if (res.pkg.getStaticSharedLibName() == null) {
6241                 mProcessLoggingHandler.invalidateBaseApkHash(res.pkg.getBaseApkPath());
6242 
6243                 // Send added for users that see the package for the first time
6244                 // sendPackageAddedForNewUsers also deals with system apps
6245                 int appId = UserHandle.getAppId(res.uid);
6246                 boolean isSystem = res.pkg.isSystem();
6247                 sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
6248                         virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds,
6249                         dataLoaderType);
6250 
6251                 // Send added for users that don't see the package for the first time
6252                 Bundle extras = new Bundle(1);
6253                 extras.putInt(Intent.EXTRA_UID, res.uid);
6254                 if (update) {
6255                     extras.putBoolean(Intent.EXTRA_REPLACING, true);
6256                 }
6257                 extras.putInt(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType);
6258                 // Send to all running apps.
6259                 final SparseArray<int[]> newBroadcastAllowList;
6260 
6261                 synchronized (mLock) {
6262                     newBroadcastAllowList = mAppsFilter.getVisibilityAllowList(
6263                             getPackageSettingInternal(res.name, Process.SYSTEM_UID),
6264                             updateUserIds, mSettings.getPackagesLocked());
6265                 }
6266                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
6267                         extras, 0 /*flags*/,
6268                         null /*targetPackage*/, null /*finishedReceiver*/,
6269                         updateUserIds, instantUserIds, newBroadcastAllowList, null);
6270                 if (installerPackageName != null) {
6271                     // Send to the installer, even if it's not running.
6272                     sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
6273                             extras, 0 /*flags*/,
6274                             installerPackageName, null /*finishedReceiver*/,
6275                             updateUserIds, instantUserIds, null /* broadcastAllowList */, null);
6276                 }
6277                 // if the required verifier is defined, but, is not the installer of record
6278                 // for the package, it gets notified
6279                 final boolean notifyVerifier = mRequiredVerifierPackage != null
6280                         && !mRequiredVerifierPackage.equals(installerPackageName);
6281                 if (notifyVerifier) {
6282                     sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
6283                             extras, 0 /*flags*/,
6284                             mRequiredVerifierPackage, null /*finishedReceiver*/,
6285                             updateUserIds, instantUserIds, null /* broadcastAllowList */, null);
6286                 }
6287                 // If package installer is defined, notify package installer about new
6288                 // app installed
6289                 if (mRequiredInstallerPackage != null) {
6290                     sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
6291                             extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND /*flags*/,
6292                             mRequiredInstallerPackage, null /*finishedReceiver*/,
6293                             firstUserIds, instantUserIds, null /* broadcastAllowList */, null);
6294                 }
6295 
6296                 // Send replaced for users that don't see the package for the first time
6297                 if (update) {
6298                     sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
6299                             packageName, extras, 0 /*flags*/,
6300                             null /*targetPackage*/, null /*finishedReceiver*/,
6301                             updateUserIds, instantUserIds, res.removedInfo.broadcastAllowList,
6302                             null);
6303                     if (installerPackageName != null) {
6304                         sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
6305                                 extras, 0 /*flags*/,
6306                                 installerPackageName, null /*finishedReceiver*/,
6307                                 updateUserIds, instantUserIds, null /*broadcastAllowList*/, null);
6308                     }
6309                     if (notifyVerifier) {
6310                         sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
6311                                 extras, 0 /*flags*/,
6312                                 mRequiredVerifierPackage, null /*finishedReceiver*/,
6313                                 updateUserIds, instantUserIds, null /*broadcastAllowList*/, null);
6314                     }
6315                     sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
6316                             null /*package*/, null /*extras*/, 0 /*flags*/,
6317                             packageName /*targetPackage*/,
6318                             null /*finishedReceiver*/, updateUserIds, instantUserIds,
6319                             null /*broadcastAllowList*/,
6320                             getTemporaryAppAllowlistBroadcastOptions(REASON_PACKAGE_REPLACED)
6321                                     .toBundle());
6322                 } else if (launchedForRestore && !res.pkg.isSystem()) {
6323                     // First-install and we did a restore, so we're responsible for the
6324                     // first-launch broadcast.
6325                     if (DEBUG_BACKUP) {
6326                         Slog.i(TAG, "Post-restore of " + packageName
6327                                 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds));
6328                     }
6329                     sendFirstLaunchBroadcast(packageName, installerPackage,
6330                             firstUserIds, firstInstantUserIds);
6331                 }
6332 
6333                 // Send broadcast package appeared if external for all users
6334                 if (res.pkg.isExternalStorage()) {
6335                     if (!update) {
6336                         final StorageManager storage = mInjector.getSystemService(
6337                                 StorageManager.class);
6338                         VolumeInfo volume =
6339                                 storage.findVolumeByUuid(
6340                                         res.pkg.getStorageUuid().toString());
6341                         int packageExternalStorageType =
6342                                 getPackageExternalStorageType(volume, res.pkg.isExternalStorage());
6343                         // If the package was installed externally, log it.
6344                         if (packageExternalStorageType != StorageEnums.UNKNOWN) {
6345                             FrameworkStatsLog.write(
6346                                     FrameworkStatsLog.APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED,
6347                                     packageExternalStorageType, packageName);
6348                         }
6349                     }
6350                     if (DEBUG_INSTALL) {
6351                         Slog.i(TAG, "upgrading pkg " + res.pkg + " is external");
6352                     }
6353                     final int[] uidArray = new int[]{res.pkg.getUid()};
6354                     ArrayList<String> pkgList = new ArrayList<>(1);
6355                     pkgList.add(packageName);
6356                     sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
6357                 }
6358             } else if (!ArrayUtils.isEmpty(res.libraryConsumers)) { // if static shared lib
6359                 int[] allUsers = mInjector.getUserManagerService().getUserIds();
6360                 for (int i = 0; i < res.libraryConsumers.size(); i++) {
6361                     AndroidPackage pkg = res.libraryConsumers.get(i);
6362                     // send broadcast that all consumers of the static shared library have changed
6363                     sendPackageChangedBroadcast(pkg.getPackageName(), false /* dontKillApp */,
6364                             new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
6365                             pkg.getUid(), null);
6366                 }
6367             }
6368 
6369             // Work that needs to happen on first install within each user
6370             if (firstUserIds != null && firstUserIds.length > 0) {
6371                 for (int userId : firstUserIds) {
6372                     restorePermissionsAndUpdateRolesForNewUserInstall(packageName,
6373                             pkgSetting.getInstallReason(userId), userId);
6374                 }
6375             }
6376 
6377             if (allNewUsers && !update) {
6378                 notifyPackageAdded(packageName, res.uid);
6379             } else {
6380                 notifyPackageChanged(packageName, res.uid);
6381             }
6382 
6383             // Log current value of "unknown sources" setting
6384             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
6385                     getUnknownSourcesSettings());
6386 
6387             // Remove the replaced package's older resources safely now
6388             InstallArgs args = res.removedInfo != null ? res.removedInfo.args : null;
6389             if (args != null) {
6390                 if (!killApp) {
6391                     // If we didn't kill the app, defer the deletion of code/resource files, since
6392                     // they may still be in use by the running application. This mitigates problems
6393                     // in cases where resources or code is loaded by a new Activity before
6394                     // ApplicationInfo changes have propagated to all application threads.
6395                     scheduleDeferredNoKillPostDelete(args);
6396                 } else {
6397                     synchronized (mInstallLock) {
6398                         args.doPostDeleteLI(true);
6399                     }
6400                 }
6401             } else {
6402                 // Force a gc to clear up things. Ask for a background one, it's fine to go on
6403                 // and not block here.
6404                 VMRuntime.getRuntime().requestConcurrentGC();
6405             }
6406 
6407             // Notify DexManager that the package was installed for new users.
6408             // The updated users should already be indexed and the package code paths
6409             // should not change.
6410             // Don't notify the manager for ephemeral apps as they are not expected to
6411             // survive long enough to benefit of background optimizations.
6412             for (int userId : firstUserIds) {
6413                 PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
6414                 // There's a race currently where some install events may interleave with an
6415                 // uninstall. This can lead to package info being null (b/36642664).
6416                 if (info != null) {
6417                     mDexManager.notifyPackageInstalled(info, userId);
6418                 }
6419             }
6420         }
6421 
6422         final boolean deferInstallObserver = succeeded && update && !killApp;
6423         if (deferInstallObserver) {
6424             scheduleDeferredNoKillInstallObserver(res, installObserver);
6425         } else {
6426             notifyInstallObserver(res, installObserver);
6427         }
6428     }
6429 
6430     @Override
notifyPackagesReplacedReceived(String[] packages)6431     public void notifyPackagesReplacedReceived(String[] packages) {
6432         final int callingUid = Binder.getCallingUid();
6433         final int callingUserId = UserHandle.getUserId(callingUid);
6434 
6435         for (String packageName : packages) {
6436             final boolean filterApp;
6437             synchronized (mLock) {
6438                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
6439                 filterApp = shouldFilterApplicationLocked(ps, callingUid, callingUserId);
6440             }
6441             if (!filterApp) {
6442                 notifyInstallObserver(packageName);
6443             }
6444         }
6445     }
6446 
notifyInstallObserver(String packageName)6447     private void notifyInstallObserver(String packageName) {
6448         Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
6449                 mNoKillInstallObservers.remove(packageName);
6450 
6451         if (pair != null) {
6452             notifyInstallObserver(pair.first, pair.second);
6453         }
6454     }
6455 
notifyInstallObserver(PackageInstalledInfo info, IPackageInstallObserver2 installObserver)6456     private void notifyInstallObserver(PackageInstalledInfo info,
6457             IPackageInstallObserver2 installObserver) {
6458         if (installObserver != null) {
6459             try {
6460                 Bundle extras = extrasForInstallResult(info);
6461                 installObserver.onPackageInstalled(info.name, info.returnCode,
6462                         info.returnMsg, extras);
6463             } catch (RemoteException e) {
6464                 Slog.i(TAG, "Observer no longer exists.");
6465             }
6466         }
6467     }
6468 
scheduleDeferredNoKillPostDelete(InstallArgs args)6469     private void scheduleDeferredNoKillPostDelete(InstallArgs args) {
6470         Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_POST_DELETE, args);
6471         mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_POST_DELETE_DELAY_MS);
6472     }
6473 
scheduleDeferredNoKillInstallObserver(PackageInstalledInfo info, IPackageInstallObserver2 observer)6474     private void scheduleDeferredNoKillInstallObserver(PackageInstalledInfo info,
6475             IPackageInstallObserver2 observer) {
6476         String packageName = info.pkg.getPackageName();
6477         mNoKillInstallObservers.put(packageName, Pair.create(info, observer));
6478         Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_INSTALL_OBSERVER, packageName);
6479         mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS);
6480     }
6481 
6482     @Override
requestChecksums(@onNull String packageName, boolean includeSplits, @Checksum.TypeMask int optional, @Checksum.TypeMask int required, @Nullable List trustedInstallers, @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId)6483     public void requestChecksums(@NonNull String packageName, boolean includeSplits,
6484             @Checksum.TypeMask int optional,
6485             @Checksum.TypeMask int required, @Nullable List trustedInstallers,
6486             @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId) {
6487         requestChecksumsInternal(packageName, includeSplits, optional, required, trustedInstallers,
6488                 onChecksumsReadyListener, userId, mInjector.getBackgroundExecutor(),
6489                 mInjector.getBackgroundHandler());
6490     }
6491 
requestChecksumsInternal(@onNull String packageName, boolean includeSplits, @Checksum.TypeMask int optional, @Checksum.TypeMask int required, @Nullable List trustedInstallers, @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId, @NonNull Executor executor, @NonNull Handler handler)6492     private void requestChecksumsInternal(@NonNull String packageName, boolean includeSplits,
6493             @Checksum.TypeMask int optional, @Checksum.TypeMask int required,
6494             @Nullable List trustedInstallers,
6495             @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId,
6496             @NonNull Executor executor, @NonNull Handler handler) {
6497         Objects.requireNonNull(packageName);
6498         Objects.requireNonNull(onChecksumsReadyListener);
6499         Objects.requireNonNull(executor);
6500         Objects.requireNonNull(handler);
6501 
6502         final ApplicationInfo applicationInfo = getApplicationInfoInternal(packageName, 0,
6503                 Binder.getCallingUid(), userId);
6504         if (applicationInfo == null) {
6505             throw new ParcelableException(new PackageManager.NameNotFoundException(packageName));
6506         }
6507         final InstallSourceInfo installSourceInfo = getInstallSourceInfo(packageName);
6508         final String installerPackageName =
6509                 installSourceInfo != null ? installSourceInfo.getInitiatingPackageName() : null;
6510 
6511         List<Pair<String, File>> filesToChecksum = new ArrayList<>();
6512 
6513         // Adding base split.
6514         filesToChecksum.add(Pair.create(null, new File(applicationInfo.sourceDir)));
6515 
6516         // Adding other splits.
6517         if (includeSplits && applicationInfo.splitNames != null) {
6518             for (int i = 0, size = applicationInfo.splitNames.length; i < size; ++i) {
6519                 filesToChecksum.add(Pair.create(applicationInfo.splitNames[i],
6520                         new File(applicationInfo.splitSourceDirs[i])));
6521             }
6522         }
6523 
6524         final Certificate[] trustedCerts = (trustedInstallers != null) ? decodeCertificates(
6525                 trustedInstallers) : null;
6526 
6527         executor.execute(() -> {
6528             ApkChecksums.Injector injector = new ApkChecksums.Injector(
6529                     () -> mContext,
6530                     () -> handler,
6531                     () -> mInjector.getIncrementalManager(),
6532                     () -> mPmInternal);
6533             ApkChecksums.getChecksums(filesToChecksum, optional, required, installerPackageName,
6534                     trustedCerts, onChecksumsReadyListener, injector);
6535         });
6536     }
6537 
decodeCertificates(@onNull List certs)6538     private static @NonNull Certificate[] decodeCertificates(@NonNull List certs) {
6539         try {
6540             final CertificateFactory cf = CertificateFactory.getInstance("X.509");
6541             final Certificate[] result = new Certificate[certs.size()];
6542             for (int i = 0, size = certs.size(); i < size; ++i) {
6543                 final InputStream is = new ByteArrayInputStream((byte[]) certs.get(i));
6544                 final X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
6545                 result[i] = cert;
6546             }
6547             return result;
6548         } catch (CertificateException e) {
6549             throw ExceptionUtils.propagate(e);
6550         }
6551     }
6552 
6553     /**
6554      * Gets the type of the external storage a package is installed on.
6555      * @param packageVolume The storage volume of the package.
6556      * @param packageIsExternal true if the package is currently installed on
6557      * external/removable/unprotected storage.
6558      * @return {@link StorageEnums#UNKNOWN} if the package is not stored externally or the
6559      * corresponding {@link StorageEnums} storage type value if it is.
6560      * corresponding {@link StorageEnums} storage type value if it is.
6561      */
getPackageExternalStorageType(VolumeInfo packageVolume, boolean packageIsExternal)6562     private static int getPackageExternalStorageType(VolumeInfo packageVolume,
6563             boolean packageIsExternal) {
6564         if (packageVolume != null) {
6565             DiskInfo disk = packageVolume.getDisk();
6566             if (disk != null) {
6567                 if (disk.isSd()) {
6568                     return StorageEnums.SD_CARD;
6569                 }
6570                 if (disk.isUsb()) {
6571                     return StorageEnums.USB;
6572                 }
6573                 if (packageIsExternal) {
6574                     return StorageEnums.OTHER;
6575                 }
6576             }
6577         }
6578         return StorageEnums.UNKNOWN;
6579     }
6580 
6581     private StorageEventListener mStorageListener = new StorageEventListener() {
6582         @Override
6583         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
6584             if (vol.type == VolumeInfo.TYPE_PRIVATE) {
6585                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
6586                     final String volumeUuid = vol.getFsUuid();
6587 
6588                     // Clean up any users or apps that were removed or recreated
6589                     // while this volume was missing
6590                     mUserManager.reconcileUsers(volumeUuid);
6591                     reconcileApps(volumeUuid);
6592 
6593                     // Clean up any install sessions that expired or were
6594                     // cancelled while this volume was missing
6595                     mInstallerService.onPrivateVolumeMounted(volumeUuid);
6596 
6597                     loadPrivatePackages(vol);
6598 
6599                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
6600                     unloadPrivatePackages(vol);
6601                 }
6602             }
6603         }
6604 
6605         @Override
6606         public void onVolumeForgotten(String fsUuid) {
6607             if (TextUtils.isEmpty(fsUuid)) {
6608                 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
6609                 return;
6610             }
6611 
6612             // Remove any apps installed on the forgotten volume
6613             synchronized (mLock) {
6614                 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
6615                 for (PackageSetting ps : packages) {
6616                     Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
6617                     deletePackageVersioned(new VersionedPackage(ps.name,
6618                             PackageManager.VERSION_CODE_HIGHEST),
6619                             new LegacyPackageDeleteObserver(null).getBinder(),
6620                             UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
6621                     // Try very hard to release any references to this package
6622                     // so we don't risk the system server being killed due to
6623                     // open FDs
6624                     AttributeCache.instance().removePackage(ps.name);
6625                 }
6626 
6627                 mSettings.onVolumeForgotten(fsUuid);
6628                 writeSettingsLPrTEMP();
6629             }
6630         }
6631     };
6632 
extrasForInstallResult(PackageInstalledInfo res)6633     Bundle extrasForInstallResult(PackageInstalledInfo res) {
6634         Bundle extras = null;
6635         switch (res.returnCode) {
6636             case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
6637                 extras = new Bundle();
6638                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
6639                         res.origPermission);
6640                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
6641                         res.origPackage);
6642                 break;
6643             }
6644             case PackageManager.INSTALL_SUCCEEDED: {
6645                 extras = new Bundle();
6646                 extras.putBoolean(Intent.EXTRA_REPLACING,
6647                         res.removedInfo != null && res.removedInfo.removedPackage != null);
6648                 break;
6649             }
6650         }
6651         return extras;
6652     }
6653 
scheduleWriteSettingsLocked()6654     void scheduleWriteSettingsLocked() {
6655         // We normally invalidate when we write settings, but in cases where we delay and
6656         // coalesce settings writes, this strategy would have us invalidate the cache too late.
6657         // Invalidating on schedule addresses this problem.
6658         invalidatePackageInfoCache();
6659         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
6660             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
6661         }
6662     }
6663 
scheduleWritePackageListLocked(int userId)6664     void scheduleWritePackageListLocked(int userId) {
6665         invalidatePackageInfoCache();
6666         if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
6667             Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
6668             msg.arg1 = userId;
6669             mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
6670         }
6671     }
6672 
scheduleWritePackageRestrictionsLocked(UserHandle user)6673     void scheduleWritePackageRestrictionsLocked(UserHandle user) {
6674         final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
6675         scheduleWritePackageRestrictionsLocked(userId);
6676     }
6677 
scheduleWritePackageRestrictionsLocked(int userId)6678     void scheduleWritePackageRestrictionsLocked(int userId) {
6679         invalidatePackageInfoCache();
6680         final int[] userIds = (userId == UserHandle.USER_ALL)
6681                 ? mUserManager.getUserIds() : new int[]{userId};
6682         for (int nextUserId : userIds) {
6683             if (!mUserManager.exists(nextUserId)) return;
6684 
6685             mDirtyUsers.add(nextUserId);
6686             if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
6687                 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
6688             }
6689         }
6690     }
6691 
main(Context context, Installer installer, @NonNull DomainVerificationService domainVerificationService, boolean factoryTest, boolean onlyCore)6692     public static PackageManagerService main(Context context, Installer installer,
6693             @NonNull DomainVerificationService domainVerificationService, boolean factoryTest,
6694             boolean onlyCore) {
6695         // Self-check for initial settings.
6696         PackageManagerServiceCompilerMapping.checkProperties();
6697         final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
6698                 Trace.TRACE_TAG_PACKAGE_MANAGER);
6699         t.traceBegin("create package manager");
6700         final PackageManagerTracedLock lock = new PackageManagerTracedLock();
6701         final Object installLock = new Object();
6702         HandlerThread backgroundThread = new HandlerThread("PackageManagerBg");
6703         backgroundThread.start();
6704         Handler backgroundHandler = new Handler(backgroundThread.getLooper());
6705 
6706         Injector injector = new Injector(
6707                 context, lock, installer, installLock, new PackageAbiHelperImpl(),
6708                 backgroundHandler,
6709                 SYSTEM_PARTITIONS,
6710                 (i, pm) -> new ComponentResolver(i.getUserManagerService(), pm.mPmInternal, lock),
6711                 (i, pm) -> PermissionManagerService.create(context,
6712                         i.getSystemConfig().getAvailableFeatures()),
6713                 (i, pm) -> new UserManagerService(context, pm,
6714                         new UserDataPreparer(installer, installLock, context, onlyCore),
6715                         lock),
6716                 (i, pm) -> new Settings(Environment.getDataDirectory(),
6717                         RuntimePermissionsPersistence.createInstance(),
6718                         i.getPermissionManagerServiceInternal(),
6719                         domainVerificationService, lock),
6720                 (i, pm) -> AppsFilter.create(pm.mPmInternal, i),
6721                 (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"),
6722                 (i, pm) -> SystemConfig.getInstance(),
6723                 (i, pm) -> new PackageDexOptimizer(i.getInstaller(), i.getInstallLock(),
6724                         i.getContext(), "*dexopt*"),
6725                 (i, pm) -> new DexManager(i.getContext(), pm, i.getPackageDexOptimizer(),
6726                         i.getInstaller(), i.getInstallLock()),
6727                 (i, pm) -> new ArtManagerService(i.getContext(), pm, i.getInstaller(),
6728                         i.getInstallLock()),
6729                 (i, pm) -> ApexManager.getInstance(),
6730                 (i, pm) -> new ViewCompiler(i.getInstallLock(), i.getInstaller()),
6731                 (i, pm) -> (IncrementalManager)
6732                         i.getContext().getSystemService(Context.INCREMENTAL_SERVICE),
6733                 (i, pm) -> new DefaultAppProvider(() -> context.getSystemService(RoleManager.class),
6734                         () -> LocalServices.getService(UserManagerInternal.class)),
6735                 (i, pm) -> new DisplayMetrics(),
6736                 (i, pm) -> new PackageParser2(pm.mSeparateProcesses, pm.mOnlyCore,
6737                         i.getDisplayMetrics(), pm.mCacheDir,
6738                         pm.mPackageParserCallback) /* scanningCachingPackageParserProducer */,
6739                 (i, pm) -> new PackageParser2(pm.mSeparateProcesses, pm.mOnlyCore,
6740                         i.getDisplayMetrics(), null,
6741                         pm.mPackageParserCallback) /* scanningPackageParserProducer */,
6742                 (i, pm) -> new PackageParser2(pm.mSeparateProcesses, false, i.getDisplayMetrics(),
6743                         null, pm.mPackageParserCallback) /* preparingPackageParserProducer */,
6744                 // Prepare a supplier of package parser for the staging manager to parse apex file
6745                 // during the staging installation.
6746                 (i, pm) -> new PackageInstallerService(
6747                         i.getContext(), pm, i::getScanningPackageParser),
6748                 (i, pm, cn) -> new InstantAppResolverConnection(
6749                         i.getContext(), cn, Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE),
6750                 (i, pm) -> new ModuleInfoProvider(i.getContext(), pm),
6751                 (i, pm) -> LegacyPermissionManagerService.create(i.getContext()),
6752                 (i, pm) -> domainVerificationService,
6753                 (i, pm) -> {
6754                     HandlerThread thread = new ServiceThread(TAG,
6755                             Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
6756                     thread.start();
6757                     return pm.new PackageHandler(thread.getLooper());
6758                 },
6759                 new DefaultSystemWrapper(),
6760                 LocalServices::getService,
6761                 context::getSystemService);
6762 
6763 
6764         if (Build.VERSION.SDK_INT <= 0) {
6765             Slog.w(TAG, "**** ro.build.version.sdk not set!");
6766         }
6767 
6768         PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest,
6769                 Build.FINGERPRINT, Build.IS_ENG, Build.IS_USERDEBUG, Build.VERSION.SDK_INT,
6770                 Build.VERSION.INCREMENTAL);
6771         t.traceEnd(); // "create package manager"
6772 
6773         final CompatChange.ChangeListener selinuxChangeListener = packageName -> {
6774             synchronized (m.mInstallLock) {
6775                 final AndroidPackage pkg;
6776                 final PackageSetting ps;
6777                 final SharedUserSetting sharedUser;
6778                 final String oldSeInfo;
6779                 synchronized (m.mLock) {
6780                     ps = m.mSettings.getPackageLPr(packageName);
6781                     if (ps == null) {
6782                         Slog.e(TAG, "Failed to find package setting " + packageName);
6783                         return;
6784                     }
6785                     pkg = ps.pkg;
6786                     sharedUser = ps.getSharedUser();
6787                     oldSeInfo = AndroidPackageUtils.getSeInfo(pkg, ps);
6788                 }
6789 
6790                 if (pkg == null) {
6791                     Slog.e(TAG, "Failed to find package " + packageName);
6792                     return;
6793                 }
6794                 final String newSeInfo = SELinuxMMAC.getSeInfo(pkg, sharedUser,
6795                         m.mInjector.getCompatibility());
6796 
6797                 if (!newSeInfo.equals(oldSeInfo)) {
6798                     Slog.i(TAG, "Updating seInfo for package " + packageName + " from: "
6799                             + oldSeInfo + " to: " + newSeInfo);
6800                     ps.getPkgState().setOverrideSeInfo(newSeInfo);
6801                     m.prepareAppDataAfterInstallLIF(pkg);
6802                 }
6803             }
6804         };
6805 
6806         injector.getCompatibility().registerListener(SELinuxMMAC.SELINUX_LATEST_CHANGES,
6807                 selinuxChangeListener);
6808         injector.getCompatibility().registerListener(SELinuxMMAC.SELINUX_R_CHANGES,
6809                 selinuxChangeListener);
6810 
6811         m.installWhitelistedSystemPackages();
6812         ServiceManager.addService("package", m);
6813         final PackageManagerNative pmn = m.new PackageManagerNative();
6814         ServiceManager.addService("package_native", pmn);
6815         return m;
6816     }
6817 
6818     /** Install/uninstall system packages for all users based on their user-type, as applicable. */
installWhitelistedSystemPackages()6819     private void installWhitelistedSystemPackages() {
6820         synchronized (mLock) {
6821             final boolean scheduleWrite = mUserManager.installWhitelistedSystemPackages(
6822                     isFirstBoot(), isDeviceUpgrading(), mExistingPackages);
6823             if (scheduleWrite) {
6824                 scheduleWritePackageRestrictionsLocked(UserHandle.USER_ALL);
6825                 scheduleWriteSettingsLocked();
6826             }
6827         }
6828     }
6829 
6830     /**
6831      * Requests that files preopted on a secondary system partition be copied to the data partition
6832      * if possible.  Note that the actual copying of the files is accomplished by init for security
6833      * reasons. This simply requests that the copy takes place and awaits confirmation of its
6834      * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
6835      */
requestCopyPreoptedFiles(Injector injector)6836     private static void requestCopyPreoptedFiles(Injector injector) {
6837         final int WAIT_TIME_MS = 100;
6838         final String CP_PREOPT_PROPERTY = "sys.cppreopt";
6839         if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
6840             SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
6841             // We will wait for up to 100 seconds.
6842             final long timeStart = SystemClock.uptimeMillis();
6843             final long timeEnd = timeStart + 100 * 1000;
6844             long timeNow = timeStart;
6845             while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
6846                 try {
6847                     Thread.sleep(WAIT_TIME_MS);
6848                 } catch (InterruptedException e) {
6849                     // Do nothing
6850                 }
6851                 timeNow = SystemClock.uptimeMillis();
6852                 if (timeNow > timeEnd) {
6853                     SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
6854                     Slog.wtf(TAG, "cppreopt did not finish!");
6855                     break;
6856                 }
6857             }
6858 
6859             Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
6860         }
6861     }
6862 
6863     @VisibleForTesting
6864     public static class ScanPartition extends SystemPartition {
6865         @ScanFlags
6866         public final int scanFlag;
6867 
ScanPartition(@onNull SystemPartition partition)6868         public ScanPartition(@NonNull SystemPartition partition) {
6869             super(partition);
6870             scanFlag = scanFlagForPartition(partition);
6871         }
6872 
6873         /**
6874          * Creates a partition containing the same folders as the original partition but with a
6875          * different root folder. The new partition will include the scan flags of the original
6876          * partition along with any specified additional scan flags.
6877          */
ScanPartition(@onNull File folder, @NonNull ScanPartition original, @ScanFlags int additionalScanFlag)6878         public ScanPartition(@NonNull File folder, @NonNull ScanPartition original,
6879                 @ScanFlags int additionalScanFlag) {
6880             super(folder, original);
6881             this.scanFlag = original.scanFlag | additionalScanFlag;
6882         }
6883 
scanFlagForPartition(PackagePartitions.SystemPartition partition)6884         private static int scanFlagForPartition(PackagePartitions.SystemPartition partition) {
6885             switch (partition.type) {
6886                 case PackagePartitions.PARTITION_SYSTEM:
6887                     return 0;
6888                 case PackagePartitions.PARTITION_VENDOR:
6889                     return SCAN_AS_VENDOR;
6890                 case PackagePartitions.PARTITION_ODM:
6891                     return SCAN_AS_ODM;
6892                 case PackagePartitions.PARTITION_OEM:
6893                     return SCAN_AS_OEM;
6894                 case PackagePartitions.PARTITION_PRODUCT:
6895                     return SCAN_AS_PRODUCT;
6896                 case PackagePartitions.PARTITION_SYSTEM_EXT:
6897                     return SCAN_AS_SYSTEM_EXT;
6898                 default:
6899                     throw new IllegalStateException("Unable to determine scan flag for "
6900                             + partition.getFolder());
6901             }
6902         }
6903 
6904         @Override
toString()6905         public String toString() {
6906             return getFolder().getAbsolutePath() + ":" + scanFlag;
6907         }
6908     }
6909 
6910     // Link watchables to the class
registerObserver()6911     private void registerObserver() {
6912         mPackages.registerObserver(mWatcher);
6913         mSharedLibraries.registerObserver(mWatcher);
6914         mStaticLibsByDeclaringPackage.registerObserver(mWatcher);
6915         mInstrumentation.registerObserver(mWatcher);
6916         mWebInstantAppsDisabled.registerObserver(mWatcher);
6917         mAppsFilter.registerObserver(mWatcher);
6918         mInstantAppRegistry.registerObserver(mWatcher);
6919         mSettings.registerObserver(mWatcher);
6920         mIsolatedOwners.registerObserver(mWatcher);
6921         mComponentResolver.registerObserver(mWatcher);
6922         // If neither "build" attribute is true then this may be a mockito test, and verification
6923         // can fail as a false positive.
6924         Watchable.verifyWatchedAttributes(this, mWatcher, !(mIsEngBuild || mIsUserDebugBuild));
6925     }
6926 
6927     /**
6928      * A extremely minimal constructor designed to start up a PackageManagerService instance for
6929      * testing.
6930      *
6931      * It is assumed that all methods under test will mock the internal fields and thus
6932      * none of the initialization is needed.
6933      */
6934     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
PackageManagerService(@onNull Injector injector, @NonNull TestParams testParams)6935     public PackageManagerService(@NonNull Injector injector, @NonNull TestParams testParams) {
6936         mInjector = injector;
6937         mInjector.bootstrap(this);
6938         mAppsFilter = injector.getAppsFilter();
6939         mComponentResolver = injector.getComponentResolver();
6940         mContext = injector.getContext();
6941         mInstaller = injector.getInstaller();
6942         mInstallLock = injector.getInstallLock();
6943         mLock = injector.getLock();
6944         mPermissionManager = injector.getPermissionManagerServiceInternal();
6945         mSettings = injector.getSettings();
6946         mUserManager = injector.getUserManagerService();
6947         mDomainVerificationManager = injector.getDomainVerificationManagerInternal();
6948         mHandler = injector.getHandler();
6949 
6950         mApexManager = testParams.apexManager;
6951         mArtManagerService = testParams.artManagerService;
6952         mAvailableFeatures = testParams.availableFeatures;
6953         mDefParseFlags = testParams.defParseFlags;
6954         mDefaultAppProvider = testParams.defaultAppProvider;
6955         mLegacyPermissionManager = testParams.legacyPermissionManagerInternal;
6956         mDexManager = testParams.dexManager;
6957         mDirsToScanAsSystem = testParams.dirsToScanAsSystem;
6958         mFactoryTest = testParams.factoryTest;
6959         mIncrementalManager = testParams.incrementalManager;
6960         mInstallerService = testParams.installerService;
6961         mInstantAppRegistry = testParams.instantAppRegistry;
6962         mInstantAppResolverConnection = testParams.instantAppResolverConnection;
6963         mInstantAppResolverSettingsComponent = testParams.instantAppResolverSettingsComponent;
6964         mIsPreNMR1Upgrade = testParams.isPreNmr1Upgrade;
6965         mIsPreNUpgrade = testParams.isPreNupgrade;
6966         mIsPreQUpgrade = testParams.isPreQupgrade;
6967         mIsUpgrade = testParams.isUpgrade;
6968         mMetrics = testParams.Metrics;
6969         mModuleInfoProvider = testParams.moduleInfoProvider;
6970         mMoveCallbacks = testParams.moveCallbacks;
6971         mOnlyCore = testParams.onlyCore;
6972         mOverlayConfig = testParams.overlayConfig;
6973         mPackageDexOptimizer = testParams.packageDexOptimizer;
6974         mPackageParserCallback = testParams.packageParserCallback;
6975         mPendingBroadcasts = testParams.pendingPackageBroadcasts;
6976         mPmInternal = testParams.pmInternal;
6977         mTestUtilityService = testParams.testUtilityService;
6978         mProcessLoggingHandler = testParams.processLoggingHandler;
6979         mProtectedPackages = testParams.protectedPackages;
6980         mSeparateProcesses = testParams.separateProcesses;
6981         mViewCompiler = testParams.viewCompiler;
6982         mRequiredVerifierPackage = testParams.requiredVerifierPackage;
6983         mRequiredInstallerPackage = testParams.requiredInstallerPackage;
6984         mRequiredUninstallerPackage = testParams.requiredUninstallerPackage;
6985         mRequiredPermissionControllerPackage = testParams.requiredPermissionControllerPackage;
6986         mSetupWizardPackage = testParams.setupWizardPackage;
6987         mStorageManagerPackage = testParams.storageManagerPackage;
6988         mDefaultTextClassifierPackage = testParams.defaultTextClassifierPackage;
6989         mSystemTextClassifierPackageName = testParams.systemTextClassifierPackage;
6990         mRetailDemoPackage = testParams.retailDemoPackage;
6991         mRecentsPackage = testParams.recentsPackage;
6992         mDocumenterPackage = testParams.documenterPackage;
6993         mConfiguratorPackage = testParams.configuratorPackage;
6994         mAppPredictionServicePackage = testParams.appPredictionServicePackage;
6995         mIncidentReportApproverPackage = testParams.incidentReportApproverPackage;
6996         mServicesExtensionPackageName = testParams.servicesExtensionPackageName;
6997         mSharedSystemSharedLibraryPackageName = testParams.sharedSystemSharedLibraryPackageName;
6998         mOverlayConfigSignaturePackage = testParams.overlayConfigSignaturePackage;
6999         mResolveComponentName = testParams.resolveComponentName;
7000 
7001         // Disable snapshots in this instance of PackageManagerService, which is only used
7002         // for testing.  The instance still needs a live computer.  The snapshot computer
7003         // is set to null since it must never be used by this instance.
7004         mSnapshotEnabled = false;
7005         mLiveComputer = createLiveComputer();
7006         mSnapshotComputer = null;
7007         mSnapshotStatistics = null;
7008 
7009         mPackages.putAll(testParams.packages);
7010         mEnableFreeCacheV2 = testParams.enableFreeCacheV2;
7011         mSdkVersion = testParams.sdkVersion;
7012         mSystemWrapper = testParams.systemWrapper;
7013         mAppInstallDir = testParams.appInstallDir;
7014         mAppLib32InstallDir = testParams.appLib32InstallDir;
7015         mIsEngBuild = testParams.isEngBuild;
7016         mIsUserDebugBuild = testParams.isUserDebugBuild;
7017         mIncrementalVersion = testParams.incrementalVersion;
7018 
7019         invalidatePackageInfoCache();
7020     }
7021 
PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest, final String buildFingerprint, final boolean isEngBuild, final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion)7022     public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest,
7023             final String buildFingerprint, final boolean isEngBuild,
7024             final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {
7025         mIsEngBuild = isEngBuild;
7026         mIsUserDebugBuild = isUserDebugBuild;
7027         mSdkVersion = sdkVersion;
7028         mIncrementalVersion = incrementalVersion;
7029         mInjector = injector;
7030         mInjector.getSystemWrapper().disablePackageCaches();
7031 
7032         final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
7033                 Trace.TRACE_TAG_PACKAGE_MANAGER);
7034         mPendingBroadcasts = new PendingPackageBroadcasts();
7035 
7036         mInjector.bootstrap(this);
7037         mLock = injector.getLock();
7038         mInstallLock = injector.getInstallLock();
7039         LockGuard.installLock(mLock, LockGuard.INDEX_PACKAGES);
7040         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
7041                 SystemClock.uptimeMillis());
7042         mSystemWrapper = injector.getSystemWrapper();
7043 
7044         mContext = injector.getContext();
7045         mFactoryTest = factoryTest;
7046         mOnlyCore = onlyCore;
7047         mMetrics = injector.getDisplayMetrics();
7048         mInstaller = injector.getInstaller();
7049         mEnableFreeCacheV2 = SystemProperties.getBoolean("fw.free_cache_v2", true);
7050 
7051         // Create sub-components that provide services / data. Order here is important.
7052         t.traceBegin("createSubComponents");
7053 
7054         // Expose private service for system components to use.
7055         mPmInternal = new PackageManagerInternalImpl();
7056         LocalServices.addService(TestUtilityService.class, this);
7057         mTestUtilityService = LocalServices.getService(TestUtilityService.class);
7058         LocalServices.addService(PackageManagerInternal.class, mPmInternal);
7059         mUserManager = injector.getUserManagerService();
7060         mComponentResolver = injector.getComponentResolver();
7061         mPermissionManager = injector.getPermissionManagerServiceInternal();
7062         mSettings = injector.getSettings();
7063         mIncrementalManager = mInjector.getIncrementalManager();
7064         mDefaultAppProvider = mInjector.getDefaultAppProvider();
7065         mLegacyPermissionManager = mInjector.getLegacyPermissionManagerInternal();
7066         PlatformCompat platformCompat = mInjector.getCompatibility();
7067         mPackageParserCallback = new PackageParser2.Callback() {
7068             @Override
7069             public boolean isChangeEnabled(long changeId, @NonNull ApplicationInfo appInfo) {
7070                 return platformCompat.isChangeEnabled(changeId, appInfo);
7071             }
7072 
7073             @Override
7074             public boolean hasFeature(String feature) {
7075                 return PackageManagerService.this.hasSystemFeature(feature, 0);
7076             }
7077         };
7078 
7079         // CHECKSTYLE:ON IndentationCheck
7080         t.traceEnd();
7081 
7082         t.traceBegin("addSharedUsers");
7083         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
7084                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7085         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
7086                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7087         mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
7088                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7089         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
7090                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7091         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
7092                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7093         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
7094                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7095         mSettings.addSharedUserLPw("android.uid.se", SE_UID,
7096                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7097         mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID,
7098                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7099         mSettings.addSharedUserLPw("android.uid.uwb", UWB_UID,
7100                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
7101         t.traceEnd();
7102 
7103         String separateProcesses = SystemProperties.get("debug.separate_processes");
7104 
7105         if (separateProcesses != null && separateProcesses.length() > 0) {
7106             if ("*".equals(separateProcesses)) {
7107                 mDefParseFlags = ParsingPackageUtils.PARSE_IGNORE_PROCESSES;
7108                 mSeparateProcesses = null;
7109                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
7110             } else {
7111                 mDefParseFlags = 0;
7112                 mSeparateProcesses = separateProcesses.split(",");
7113                 Slog.w(TAG, "Running with debug.separate_processes: "
7114                         + separateProcesses);
7115             }
7116         } else {
7117             mDefParseFlags = 0;
7118             mSeparateProcesses = null;
7119         }
7120 
7121         mPackageDexOptimizer = injector.getPackageDexOptimizer();
7122         mDexManager = injector.getDexManager();
7123         mArtManagerService = injector.getArtManagerService();
7124         mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
7125         mViewCompiler = injector.getViewCompiler();
7126 
7127         mContext.getSystemService(DisplayManager.class)
7128                 .getDisplay(Display.DEFAULT_DISPLAY).getMetrics(mMetrics);
7129 
7130         t.traceBegin("get system config");
7131         SystemConfig systemConfig = injector.getSystemConfig();
7132         mAvailableFeatures = systemConfig.getAvailableFeatures();
7133         t.traceEnd();
7134 
7135         mProtectedPackages = new ProtectedPackages(mContext);
7136 
7137         mApexManager = injector.getApexManager();
7138         mAppsFilter = mInjector.getAppsFilter();
7139 
7140         final List<ScanPartition> scanPartitions = new ArrayList<>();
7141         final List<ApexManager.ActiveApexInfo> activeApexInfos = mApexManager.getActiveApexInfos();
7142         for (int i = 0; i < activeApexInfos.size(); i++) {
7143             final ScanPartition scanPartition = resolveApexToScanPartition(activeApexInfos.get(i));
7144             if (scanPartition != null) {
7145                 scanPartitions.add(scanPartition);
7146             }
7147         }
7148 
7149         mInstantAppRegistry = new InstantAppRegistry(this, mPermissionManager);
7150 
7151         mDirsToScanAsSystem = new ArrayList<>();
7152         mDirsToScanAsSystem.addAll(injector.getSystemPartitions());
7153         mDirsToScanAsSystem.addAll(scanPartitions);
7154         Slog.d(TAG, "Directories scanned as system partitions: " + mDirsToScanAsSystem);
7155 
7156         mAppInstallDir = new File(Environment.getDataDirectory(), "app");
7157         mAppLib32InstallDir = getAppLib32InstallDir();
7158 
7159         mDomainVerificationManager = injector.getDomainVerificationManagerInternal();
7160         mDomainVerificationManager.setConnection(mDomainVerificationConnection);
7161 
7162         synchronized (mLock) {
7163             // Create the computer as soon as the state objects have been installed.  The
7164             // cached computer is the same as the live computer until the end of the
7165             // constructor, at which time the invalidation method updates it.  The cache is
7166             // corked initially to ensure a cached computer is not built until the end of the
7167             // constructor.
7168             mSnapshotStatistics = new SnapshotStatistics();
7169             sSnapshotConsumer = this;
7170             sSnapshotCorked.set(1);
7171             sSnapshotInvalid.set(true);
7172             mLiveComputer = createLiveComputer();
7173             mSnapshotComputer = null;
7174             mSnapshotEnabled = SNAPSHOT_ENABLED;
7175             registerObserver();
7176         }
7177 
7178         // CHECKSTYLE:OFF IndentationCheck
7179         synchronized (mInstallLock) {
7180         // writer
7181         synchronized (mLock) {
7182             mHandler = injector.getHandler();
7183             mProcessLoggingHandler = new ProcessLoggingHandler();
7184             Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
7185 
7186             ArrayMap<String, SystemConfig.SharedLibraryEntry> libConfig
7187                     = systemConfig.getSharedLibraries();
7188             final int builtInLibCount = libConfig.size();
7189             for (int i = 0; i < builtInLibCount; i++) {
7190                 addBuiltInSharedLibraryLocked(libConfig.valueAt(i));
7191             }
7192 
7193             // Now that we have added all the libraries, iterate again to add dependency
7194             // information IFF their dependencies are added.
7195             long undefinedVersion = SharedLibraryInfo.VERSION_UNDEFINED;
7196             for (int i = 0; i < builtInLibCount; i++) {
7197                 String name = libConfig.keyAt(i);
7198                 SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
7199                 final int dependencyCount = entry.dependencies.length;
7200                 for (int j = 0; j < dependencyCount; j++) {
7201                     final SharedLibraryInfo dependency =
7202                         getSharedLibraryInfoLPr(entry.dependencies[j], undefinedVersion);
7203                     if (dependency != null) {
7204                         getSharedLibraryInfoLPr(name, undefinedVersion).addDependency(dependency);
7205                     }
7206                 }
7207             }
7208 
7209             SELinuxMMAC.readInstallPolicy();
7210 
7211             t.traceBegin("loadFallbacks");
7212             FallbackCategoryProvider.loadFallbacks();
7213             t.traceEnd();
7214 
7215             t.traceBegin("read user settings");
7216             mFirstBoot = !mSettings.readLPw(mInjector.getUserManagerInternal().getUsers(
7217                     /* excludePartial= */ true,
7218                     /* excludeDying= */ false,
7219                     /* excludePreCreated= */ false));
7220             t.traceEnd();
7221 
7222             mPermissionManager.readLegacyPermissionsTEMP(mSettings.mPermissions);
7223 
7224             if (!mOnlyCore && mFirstBoot) {
7225                 requestCopyPreoptedFiles(mInjector);
7226             }
7227 
7228             String customResolverActivityName = Resources.getSystem().getString(
7229                     R.string.config_customResolverActivity);
7230             if (!TextUtils.isEmpty(customResolverActivityName)) {
7231                 mCustomResolverComponentName = ComponentName.unflattenFromString(
7232                         customResolverActivityName);
7233             }
7234 
7235             long startTime = SystemClock.uptimeMillis();
7236 
7237             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
7238                     startTime);
7239 
7240             final String bootClassPath = System.getenv("BOOTCLASSPATH");
7241             final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
7242 
7243             if (bootClassPath == null) {
7244                 Slog.w(TAG, "No BOOTCLASSPATH found!");
7245             }
7246 
7247             if (systemServerClassPath == null) {
7248                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
7249             }
7250 
7251             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
7252 
7253             final VersionInfo ver = mSettings.getInternalVersion();
7254             mIsUpgrade =
7255                     !buildFingerprint.equals(ver.fingerprint);
7256             if (mIsUpgrade) {
7257                 PackageManagerServiceUtils.logCriticalInfo(Log.INFO,
7258                         "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
7259             }
7260 
7261             // when upgrading from pre-M, promote system app permissions from install to runtime
7262             mPromoteSystemApps =
7263                     mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
7264 
7265             // When upgrading from pre-N, we need to handle package extraction like first boot,
7266             // as there is no profiling data available.
7267             mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
7268 
7269             mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
7270             mIsPreQUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.Q;
7271 
7272             final WatchedArrayMap<String, PackageSetting> packageSettings =
7273                 mSettings.getPackagesLocked();
7274 
7275             // Save the names of pre-existing packages prior to scanning, so we can determine
7276             // which system packages are completely new due to an upgrade.
7277             if (isDeviceUpgrading()) {
7278                 mExistingPackages = new ArraySet<>(packageSettings.size());
7279                 for (PackageSetting ps : packageSettings.values()) {
7280                     mExistingPackages.add(ps.name);
7281                 }
7282             }
7283 
7284             mCacheDir = preparePackageParserCache(mIsEngBuild);
7285 
7286             // Set flag to monitor and not change apk file paths when
7287             // scanning install directories.
7288             int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
7289 
7290             if (mIsUpgrade || mFirstBoot) {
7291                 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
7292             }
7293 
7294             final int systemParseFlags = mDefParseFlags | ParsingPackageUtils.PARSE_IS_SYSTEM_DIR;
7295             final int systemScanFlags = scanFlags | SCAN_AS_SYSTEM;
7296 
7297             PackageParser2 packageParser = injector.getScanningCachingPackageParser();
7298 
7299             ExecutorService executorService = ParallelPackageParser.makeExecutorService();
7300             // Prepare apex package info before scanning APKs, these information are needed when
7301             // scanning apk in apex.
7302             mApexManager.scanApexPackagesTraced(packageParser, executorService);
7303             // Collect vendor/product/system_ext overlay packages. (Do this before scanning
7304             // any apps.)
7305             // For security and version matching reason, only consider overlay packages if they
7306             // reside in the right directory.
7307             for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
7308                 final ScanPartition partition = mDirsToScanAsSystem.get(i);
7309                 if (partition.getOverlayFolder() == null) {
7310                     continue;
7311                 }
7312                 scanDirTracedLI(partition.getOverlayFolder(), systemParseFlags,
7313                         systemScanFlags | partition.scanFlag, 0,
7314                         packageParser, executorService);
7315             }
7316 
7317             scanDirTracedLI(frameworkDir, systemParseFlags,
7318                     systemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED, 0,
7319                     packageParser, executorService);
7320             if (!mPackages.containsKey("android")) {
7321                 throw new IllegalStateException(
7322                         "Failed to load frameworks package; check log for warnings");
7323             }
7324             for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
7325                 final ScanPartition partition = mDirsToScanAsSystem.get(i);
7326                 if (partition.getPrivAppFolder() != null) {
7327                     scanDirTracedLI(partition.getPrivAppFolder(), systemParseFlags,
7328                             systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0,
7329                             packageParser, executorService);
7330                 }
7331                 scanDirTracedLI(partition.getAppFolder(), systemParseFlags,
7332                         systemScanFlags | partition.scanFlag, 0,
7333                         packageParser, executorService);
7334             }
7335 
7336             // Parse overlay configuration files to set default enable state, mutability, and
7337             // priority of system overlays.
7338             mOverlayConfig = OverlayConfig.initializeSystemInstance(
7339                     consumer -> mPmInternal.forEachPackage(
7340                             pkg -> consumer.accept(pkg, pkg.isSystem())));
7341 
7342             // Prune any system packages that no longer exist.
7343             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
7344             // Stub packages must either be replaced with full versions in the /data
7345             // partition or be disabled.
7346             final List<String> stubSystemApps = new ArrayList<>();
7347             final int[] userIds = mUserManager.getUserIds();
7348             if (!mOnlyCore) {
7349                 // do this first before mucking with mPackages for the "expecting better" case
7350                 final int numPackages = mPackages.size();
7351                 for (int index = 0; index < numPackages; index++) {
7352                     final AndroidPackage pkg = mPackages.valueAt(index);
7353                     if (pkg.isStub()) {
7354                         stubSystemApps.add(pkg.getPackageName());
7355                     }
7356                 }
7357 
7358                 // Iterates PackageSettings in reversed order because the item could be removed
7359                 // during the iteration.
7360                 for (int index = packageSettings.size() - 1; index >= 0; index--) {
7361                     final PackageSetting ps = packageSettings.valueAt(index);
7362 
7363                     /*
7364                      * If this is not a system app, it can't be a
7365                      * disable system app.
7366                      */
7367                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7368                         continue;
7369                     }
7370 
7371                     /*
7372                      * If the package is scanned, it's not erased.
7373                      */
7374                     final AndroidPackage scannedPkg = mPackages.get(ps.name);
7375                     if (scannedPkg != null) {
7376                         /*
7377                          * If the system app is both scanned and in the
7378                          * disabled packages list, then it must have been
7379                          * added via OTA. Remove it from the currently
7380                          * scanned package so the previously user-installed
7381                          * application can be scanned.
7382                          */
7383                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
7384                             logCriticalInfo(Log.WARN,
7385                                     "Expecting better updated system app for " + ps.name
7386                                     + "; removing system app.  Last known"
7387                                     + " codePath=" + ps.getPathString()
7388                                     + ", versionCode=" + ps.versionCode
7389                                     + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
7390                             removePackageLI(scannedPkg, true);
7391                             mExpectingBetter.put(ps.name, ps.getPath());
7392                         }
7393 
7394                         continue;
7395                     }
7396 
7397                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
7398                         logCriticalInfo(Log.WARN, "System package " + ps.name
7399                                 + " no longer exists; it's data will be wiped");
7400                         removePackageDataLIF(ps, userIds, null, 0, false);
7401                     } else {
7402                         // we still have a disabled system package, but, it still might have
7403                         // been removed. check the code path still exists and check there's
7404                         // still a package. the latter can happen if an OTA keeps the same
7405                         // code path, but, changes the package name.
7406                         final PackageSetting disabledPs =
7407                                 mSettings.getDisabledSystemPkgLPr(ps.name);
7408                         if (disabledPs.getPath() == null || !disabledPs.getPath().exists()
7409                                 || disabledPs.pkg == null) {
7410                             possiblyDeletedUpdatedSystemApps.add(ps.name);
7411                         } else {
7412                             // We're expecting that the system app should remain disabled, but add
7413                             // it to expecting better to recover in case the data version cannot
7414                             // be scanned.
7415                             mExpectingBetter.put(disabledPs.name, disabledPs.getPath());
7416                         }
7417                     }
7418                 }
7419             }
7420 
7421             final int cachedSystemApps = PackageCacher.sCachedPackageReadCount.get();
7422 
7423             // Remove any shared userIDs that have no associated packages
7424             mSettings.pruneSharedUsersLPw();
7425             final long systemScanTime = SystemClock.uptimeMillis() - startTime;
7426             final int systemPackagesCount = mPackages.size();
7427             Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
7428                     + " ms, packageCount: " + systemPackagesCount
7429                     + " , timePerPackage: "
7430                     + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
7431                     + " , cached: " + cachedSystemApps);
7432             if (mIsUpgrade && systemPackagesCount > 0) {
7433                 //CHECKSTYLE:OFF IndentationCheck
7434                 FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
7435                     BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME,
7436                     systemScanTime / systemPackagesCount);
7437                 //CHECKSTYLE:ON IndentationCheck
7438             }
7439             if (!mOnlyCore) {
7440                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
7441                         SystemClock.uptimeMillis());
7442                 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0,
7443                         packageParser, executorService);
7444 
7445             }
7446 
7447             packageParser.close();
7448 
7449             List<Runnable> unfinishedTasks = executorService.shutdownNow();
7450             if (!unfinishedTasks.isEmpty()) {
7451                 throw new IllegalStateException("Not all tasks finished before calling close: "
7452                         + unfinishedTasks);
7453             }
7454 
7455             if (!mOnlyCore) {
7456                 // Remove disable package settings for updated system apps that were
7457                 // removed via an OTA. If the update is no longer present, remove the
7458                 // app completely. Otherwise, revoke their system privileges.
7459                 for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
7460                     final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
7461                     final AndroidPackage pkg = mPackages.get(packageName);
7462                     final String msg;
7463 
7464                     // remove from the disabled system list; do this first so any future
7465                     // scans of this package are performed without this state
7466                     mSettings.removeDisabledSystemPackageLPw(packageName);
7467 
7468                     if (pkg == null) {
7469                         // should have found an update, but, we didn't; remove everything
7470                         msg = "Updated system package " + packageName
7471                                 + " no longer exists; removing its data";
7472                         // Actual deletion of code and data will be handled by later
7473                         // reconciliation step
7474                     } else {
7475                         // found an update; revoke system privileges
7476                         msg = "Updated system package " + packageName
7477                                 + " no longer exists; rescanning package on data";
7478 
7479                         // NOTE: We don't do anything special if a stub is removed from the
7480                         // system image. But, if we were [like removing the uncompressed
7481                         // version from the /data partition], this is where it'd be done.
7482 
7483                         // remove the package from the system and re-scan it without any
7484                         // special privileges
7485                         removePackageLI(pkg, true);
7486                         try {
7487                             final File codePath = new File(pkg.getPath());
7488                             scanPackageTracedLI(codePath, 0, scanFlags, 0, null);
7489                         } catch (PackageManagerException e) {
7490                             Slog.e(TAG, "Failed to parse updated, ex-system package: "
7491                                     + e.getMessage());
7492                         }
7493                     }
7494 
7495                     // one final check. if we still have a package setting [ie. it was
7496                     // previously scanned and known to the system], but, we don't have
7497                     // a package [ie. there was an error scanning it from the /data
7498                     // partition], completely remove the package data.
7499                     final PackageSetting ps = mSettings.getPackageLPr(packageName);
7500                     if (ps != null && mPackages.get(packageName) == null) {
7501                         removePackageDataLIF(ps, userIds, null, 0, false);
7502 
7503                     }
7504                     logCriticalInfo(Log.WARN, msg);
7505                 }
7506 
7507                 /*
7508                  * Make sure all system apps that we expected to appear on
7509                  * the userdata partition actually showed up. If they never
7510                  * appeared, crawl back and revive the system version.
7511                  */
7512                 for (int i = 0; i < mExpectingBetter.size(); i++) {
7513                     final String packageName = mExpectingBetter.keyAt(i);
7514                     if (!mPackages.containsKey(packageName)) {
7515                         final File scanFile = mExpectingBetter.valueAt(i);
7516 
7517                         logCriticalInfo(Log.WARN, "Expected better " + packageName
7518                                 + " but never showed up; reverting to system");
7519 
7520                         @ParseFlags int reparseFlags = 0;
7521                         @ScanFlags int rescanFlags = 0;
7522                         for (int i1 = mDirsToScanAsSystem.size() - 1; i1 >= 0; i1--) {
7523                             final ScanPartition partition = mDirsToScanAsSystem.get(i1);
7524                             if (partition.containsPrivApp(scanFile)) {
7525                                 reparseFlags = systemParseFlags;
7526                                 rescanFlags = systemScanFlags | SCAN_AS_PRIVILEGED
7527                                         | partition.scanFlag;
7528                                 break;
7529                             }
7530                             if (partition.containsApp(scanFile)) {
7531                                 reparseFlags = systemParseFlags;
7532                                 rescanFlags = systemScanFlags | partition.scanFlag;
7533                                 break;
7534                             }
7535                         }
7536                         if (rescanFlags == 0) {
7537                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
7538                             continue;
7539                         }
7540                         mSettings.enableSystemPackageLPw(packageName);
7541 
7542                         try {
7543                             final AndroidPackage newPkg = scanPackageTracedLI(
7544                                     scanFile, reparseFlags, rescanFlags, 0, null);
7545                             // We rescanned a stub, add it to the list of stubbed system packages
7546                             if (newPkg.isStub()) {
7547                                 stubSystemApps.add(packageName);
7548                             }
7549                         } catch (PackageManagerException e) {
7550                             Slog.e(TAG, "Failed to parse original system package: "
7551                                     + e.getMessage());
7552                         }
7553                     }
7554                 }
7555 
7556                 // Uncompress and install any stubbed system applications.
7557                 // This must be done last to ensure all stubs are replaced or disabled.
7558                 installSystemStubPackages(stubSystemApps, scanFlags);
7559 
7560                 final int cachedNonSystemApps = PackageCacher.sCachedPackageReadCount.get()
7561                                 - cachedSystemApps;
7562 
7563                 final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
7564                 final int dataPackagesCount = mPackages.size() - systemPackagesCount;
7565                 Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
7566                         + " ms, packageCount: " + dataPackagesCount
7567                         + " , timePerPackage: "
7568                         + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
7569                         + " , cached: " + cachedNonSystemApps);
7570                 if (mIsUpgrade && dataPackagesCount > 0) {
7571                     //CHECKSTYLE:OFF IndentationCheck
7572                     FrameworkStatsLog.write(
7573                         FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
7574                         BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME,
7575                         dataScanTime / dataPackagesCount);
7576                     //CHECKSTYLE:OFF IndentationCheck
7577                 }
7578             }
7579             mExpectingBetter.clear();
7580 
7581             // Resolve the storage manager.
7582             mStorageManagerPackage = getStorageManagerPackageName();
7583 
7584             // Resolve protected action filters. Only the setup wizard is allowed to
7585             // have a high priority filter for these actions.
7586             mSetupWizardPackage = getSetupWizardPackageNameImpl();
7587             mComponentResolver.fixProtectedFilterPriorities();
7588 
7589             mDefaultTextClassifierPackage = getDefaultTextClassifierPackageName();
7590             mSystemTextClassifierPackageName = getSystemTextClassifierPackageName();
7591             mDocumenterPackage = getDocumenterPackageName();
7592             mConfiguratorPackage = getDeviceConfiguratorPackageName();
7593             mAppPredictionServicePackage = getAppPredictionServicePackageName();
7594             mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
7595             mRetailDemoPackage = getRetailDemoPackageName();
7596             mOverlayConfigSignaturePackage = getOverlayConfigSignaturePackageName();
7597             mRecentsPackage = getRecentsPackageName();
7598 
7599             // Now that we know all of the shared libraries, update all clients to have
7600             // the correct library paths.
7601             updateAllSharedLibrariesLocked(null, null, Collections.unmodifiableMap(mPackages));
7602 
7603             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
7604                 // NOTE: We ignore potential failures here during a system scan (like
7605                 // the rest of the commands above) because there's precious little we
7606                 // can do about it. A settings error is reported, though.
7607                 final List<String> changedAbiCodePath =
7608                         applyAdjustedAbiToSharedUser(setting, null /*scannedPackage*/,
7609                         mInjector.getAbiHelper().getAdjustedAbiForSharedUser(
7610                                 setting.packages, null /*scannedPackage*/));
7611                 if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
7612                     for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
7613                         final String codePathString = changedAbiCodePath.get(i);
7614                         try {
7615                             mInstaller.rmdex(codePathString,
7616                                     getDexCodeInstructionSet(getPreferredInstructionSet()));
7617                         } catch (InstallerException ignored) {
7618                         }
7619                     }
7620                 }
7621                 // Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
7622                 // SELinux domain.
7623                 setting.fixSeInfoLocked();
7624                 setting.updateProcesses();
7625             }
7626 
7627             // Now that we know all the packages we are keeping,
7628             // read and update their last usage times.
7629             mPackageUsage.read(packageSettings);
7630             mCompilerStats.read();
7631 
7632             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
7633                     SystemClock.uptimeMillis());
7634             Slog.i(TAG, "Time to scan packages: "
7635                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
7636                     + " seconds");
7637 
7638             mPermissionManager.readLegacyPermissionStateTEMP();
7639             // If the build fingerprint has changed since the last time we booted,
7640             // we need to re-grant app permission to catch any new ones that
7641             // appear.  This is really a hack, and means that apps can in some
7642             // cases get permissions that the user didn't initially explicitly
7643             // allow...  it would be nice to have some better way to handle
7644             // this situation.
7645             if (mIsUpgrade) {
7646                 Slog.i(TAG, "Build fingerprint changed from " + ver.fingerprint + " to "
7647                         + Build.FINGERPRINT + "; regranting permissions for internal storage");
7648             }
7649             mPermissionManager.onStorageVolumeMounted(
7650                     StorageManager.UUID_PRIVATE_INTERNAL, mIsUpgrade);
7651             ver.sdkVersion = mSdkVersion;
7652 
7653             // If this is the first boot or an update from pre-M, and it is a normal
7654             // boot, then we need to initialize the default preferred apps across
7655             // all defined users.
7656             if (!mOnlyCore && (mPromoteSystemApps || mFirstBoot)) {
7657                 for (UserInfo user : mInjector.getUserManagerInternal().getUsers(true)) {
7658                     mSettings.applyDefaultPreferredAppsLPw(user.id);
7659                 }
7660             }
7661 
7662             // Prepare storage for system user really early during boot,
7663             // since core system apps like SettingsProvider and SystemUI
7664             // can't wait for user to start
7665             final int storageFlags;
7666             if (StorageManager.isFileEncryptedNativeOrEmulated()) {
7667                 storageFlags = StorageManager.FLAG_STORAGE_DE;
7668             } else {
7669                 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
7670             }
7671             List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
7672                     UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
7673                     true /* onlyCoreApps */);
7674             mPrepareAppDataFuture = SystemServerInitThreadPool.submit(() -> {
7675                 TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
7676                         Trace.TRACE_TAG_PACKAGE_MANAGER);
7677                 traceLog.traceBegin("AppDataFixup");
7678                 try {
7679                     mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
7680                             StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
7681                 } catch (InstallerException e) {
7682                     Slog.w(TAG, "Trouble fixing GIDs", e);
7683                 }
7684                 traceLog.traceEnd();
7685 
7686                 traceLog.traceBegin("AppDataPrepare");
7687                 if (deferPackages == null || deferPackages.isEmpty()) {
7688                     return;
7689                 }
7690                 int count = 0;
7691                 final Installer.Batch batch = new Installer.Batch();
7692                 for (String pkgName : deferPackages) {
7693                     AndroidPackage pkg = null;
7694                     synchronized (mLock) {
7695                         PackageSetting ps = mSettings.getPackageLPr(pkgName);
7696                         if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
7697                             pkg = ps.pkg;
7698                         }
7699                     }
7700                     if (pkg != null) {
7701                         prepareAppDataAndMigrate(batch, pkg, UserHandle.USER_SYSTEM, storageFlags,
7702                                 true /* maybeMigrateAppData */);
7703                         count++;
7704                     }
7705                 }
7706                 synchronized (mInstallLock) {
7707                     executeBatchLI(batch);
7708                 }
7709                 traceLog.traceEnd();
7710                 Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
7711             }, "prepareAppData");
7712 
7713             // If this is first boot after an OTA, and a normal boot, then
7714             // we need to clear code cache directories.
7715             // Note that we do *not* clear the application profiles. These remain valid
7716             // across OTAs and are used to drive profile verification (post OTA) and
7717             // profile compilation (without waiting to collect a fresh set of profiles).
7718             if (mIsUpgrade && !mOnlyCore) {
7719                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
7720                 for (int i = 0; i < packageSettings.size(); i++) {
7721                     final PackageSetting ps = packageSettings.valueAt(i);
7722                     if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
7723                         // No apps are running this early, so no need to freeze
7724                         clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
7725                                 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
7726                                         | Installer.FLAG_CLEAR_CODE_CACHE_ONLY
7727                                         | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
7728                     }
7729                 }
7730                 ver.fingerprint = Build.FINGERPRINT;
7731             }
7732 
7733             // Legacy existing (installed before Q) non-system apps to hide
7734             // their icons in launcher.
7735             if (!mOnlyCore && mIsPreQUpgrade) {
7736                 Slog.i(TAG, "Whitelisting all existing apps to hide their icons");
7737                 int size = packageSettings.size();
7738                 for (int i = 0; i < size; i++) {
7739                     final PackageSetting ps = packageSettings.valueAt(i);
7740                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7741                         continue;
7742                     }
7743                     ps.disableComponentLPw(PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME,
7744                             UserHandle.USER_SYSTEM);
7745                 }
7746             }
7747 
7748             // clear only after permissions and other defaults have been updated
7749             mPromoteSystemApps = false;
7750 
7751             // All the changes are done during package scanning.
7752             ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
7753 
7754             // can downgrade to reader
7755             t.traceBegin("write settings");
7756             writeSettingsLPrTEMP();
7757             t.traceEnd();
7758             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
7759                     SystemClock.uptimeMillis());
7760 
7761             if (!mOnlyCore) {
7762                 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
7763                 mRequiredInstallerPackage = getRequiredInstallerLPr();
7764                 mRequiredUninstallerPackage = getRequiredUninstallerLPr();
7765                 ComponentName intentFilterVerifierComponent =
7766                         getIntentFilterVerifierComponentNameLPr();
7767                 ComponentName domainVerificationAgent =
7768                         getDomainVerificationAgentComponentNameLPr();
7769 
7770                 DomainVerificationProxy domainVerificationProxy = DomainVerificationProxy.makeProxy(
7771                         intentFilterVerifierComponent, domainVerificationAgent, mContext,
7772                         mDomainVerificationManager, mDomainVerificationManager.getCollector(),
7773                         mDomainVerificationConnection);
7774 
7775                 mDomainVerificationManager.setProxy(domainVerificationProxy);
7776 
7777                 mServicesExtensionPackageName = getRequiredServicesExtensionPackageLPr();
7778                 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
7779                         PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
7780                         SharedLibraryInfo.VERSION_UNDEFINED);
7781             } else {
7782                 mRequiredVerifierPackage = null;
7783                 mRequiredInstallerPackage = null;
7784                 mRequiredUninstallerPackage = null;
7785                 mServicesExtensionPackageName = null;
7786                 mSharedSystemSharedLibraryPackageName = null;
7787             }
7788 
7789             // PermissionController hosts default permission granting and role management, so it's a
7790             // critical part of the core system.
7791             mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr();
7792 
7793             mSettings.setPermissionControllerVersion(
7794                     getPackageInfo(mRequiredPermissionControllerPackage, 0,
7795                             UserHandle.USER_SYSTEM).getLongVersionCode());
7796 
7797             // Initialize InstantAppRegistry's Instant App list for all users.
7798             for (AndroidPackage pkg : mPackages.values()) {
7799                 if (pkg.isSystem()) {
7800                     continue;
7801                 }
7802                 for (int userId : userIds) {
7803                     final PackageSetting ps = getPackageSetting(pkg.getPackageName());
7804                     if (ps == null || !ps.getInstantApp(userId) || !ps.getInstalled(userId)) {
7805                         continue;
7806                     }
7807                     mInstantAppRegistry.addInstantAppLPw(userId, ps.appId);
7808                 }
7809             }
7810 
7811             mInstallerService = mInjector.getPackageInstallerService();
7812             final ComponentName instantAppResolverComponent = getInstantAppResolverLPr();
7813             if (instantAppResolverComponent != null) {
7814                 if (DEBUG_INSTANT) {
7815                     Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
7816                 }
7817                 mInstantAppResolverConnection =
7818                         mInjector.getInstantAppResolverConnection(instantAppResolverComponent);
7819                 mInstantAppResolverSettingsComponent =
7820                         getInstantAppResolverSettingsLPr(instantAppResolverComponent);
7821             } else {
7822                 mInstantAppResolverConnection = null;
7823                 mInstantAppResolverSettingsComponent = null;
7824             }
7825             updateInstantAppInstallerLocked(null);
7826 
7827             // Read and update the usage of dex files.
7828             // Do this at the end of PM init so that all the packages have their
7829             // data directory reconciled.
7830             // At this point we know the code paths of the packages, so we can validate
7831             // the disk file and build the internal cache.
7832             // The usage file is expected to be small so loading and verifying it
7833             // should take a fairly small time compare to the other activities (e.g. package
7834             // scanning).
7835             final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
7836             for (int userId : userIds) {
7837                 userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
7838             }
7839             mDexManager.load(userPackages);
7840             if (mIsUpgrade) {
7841                 FrameworkStatsLog.write(
7842                         FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
7843                         BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_INIT_TIME,
7844                         SystemClock.uptimeMillis() - startTime);
7845             }
7846 
7847             // Rebild the live computer since some attributes have been rebuilt.
7848             mLiveComputer = createLiveComputer();
7849 
7850         } // synchronized (mLock)
7851         } // synchronized (mInstallLock)
7852         // CHECKSTYLE:ON IndentationCheck
7853 
7854         mModuleInfoProvider = mInjector.getModuleInfoProvider();
7855         mInjector.getSystemWrapper().enablePackageCaches();
7856 
7857         // Now after opening every single application zip, make sure they
7858         // are all flushed.  Not really needed, but keeps things nice and
7859         // tidy.
7860         t.traceBegin("GC");
7861         VMRuntime.getRuntime().requestConcurrentGC();
7862         t.traceEnd();
7863 
7864         // The initial scanning above does many calls into installd while
7865         // holding the mPackages lock, but we're mostly interested in yelling
7866         // once we have a booted system.
7867         mInstaller.setWarnIfHeld(mLock);
7868 
7869         ParsingPackageUtils.readConfigUseRoundIcon(mContext.getResources());
7870 
7871         mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);
7872 
7873         Slog.i(TAG, "Fix for b/169414761 is applied");
7874     }
7875 
7876     /**
7877      * Uncompress and install stub applications.
7878      * <p>In order to save space on the system partition, some applications are shipped in a
7879      * compressed form. In addition the compressed bits for the full application, the
7880      * system image contains a tiny stub comprised of only the Android manifest.
7881      * <p>During the first boot, attempt to uncompress and install the full application. If
7882      * the application can't be installed for any reason, disable the stub and prevent
7883      * uncompressing the full application during future boots.
7884      * <p>In order to forcefully attempt an installation of a full application, go to app
7885      * settings and enable the application.
7886      */
installSystemStubPackages(@onNull List<String> systemStubPackageNames, @ScanFlags int scanFlags)7887     private void installSystemStubPackages(@NonNull List<String> systemStubPackageNames,
7888             @ScanFlags int scanFlags) {
7889         for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) {
7890             final String packageName = systemStubPackageNames.get(i);
7891             // skip if the system package is already disabled
7892             if (mSettings.isDisabledSystemPackageLPr(packageName)) {
7893                 systemStubPackageNames.remove(i);
7894                 continue;
7895             }
7896             // skip if the package isn't installed (?!); this should never happen
7897             final AndroidPackage pkg = mPackages.get(packageName);
7898             if (pkg == null) {
7899                 systemStubPackageNames.remove(i);
7900                 continue;
7901             }
7902             // skip if the package has been disabled by the user
7903             final PackageSetting ps = mSettings.getPackageLPr(packageName);
7904             if (ps != null) {
7905                 final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
7906                 if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
7907                     systemStubPackageNames.remove(i);
7908                     continue;
7909                 }
7910             }
7911 
7912             // install the package to replace the stub on /system
7913             try {
7914                 installStubPackageLI(pkg, 0, scanFlags);
7915                 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
7916                         UserHandle.USER_SYSTEM, "android");
7917                 systemStubPackageNames.remove(i);
7918             } catch (PackageManagerException e) {
7919                 Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
7920             }
7921 
7922             // any failed attempt to install the package will be cleaned up later
7923         }
7924 
7925         // disable any stub still left; these failed to install the full application
7926         for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) {
7927             final String pkgName = systemStubPackageNames.get(i);
7928             final PackageSetting ps = mSettings.getPackageLPr(pkgName);
7929             ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
7930                     UserHandle.USER_SYSTEM, "android");
7931             logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
7932         }
7933     }
7934 
7935     /**
7936      * Extract, install and enable a stub package.
7937      * <p>If the compressed file can not be extracted / installed for any reason, the stub
7938      * APK will be installed and the package will be disabled. To recover from this situation,
7939      * the user will need to go into system settings and re-enable the package.
7940      */
enableCompressedPackage(AndroidPackage stubPkg, @NonNull PackageSetting stubPkgSetting)7941     private boolean enableCompressedPackage(AndroidPackage stubPkg,
7942             @NonNull PackageSetting stubPkgSetting) {
7943         final int parseFlags = mDefParseFlags | ParsingPackageUtils.PARSE_CHATTY
7944                 | PackageParser.PARSE_ENFORCE_CODE;
7945         synchronized (mInstallLock) {
7946             final AndroidPackage pkg;
7947             try (PackageFreezer freezer =
7948                     freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
7949                 pkg = installStubPackageLI(stubPkg, parseFlags, 0 /*scanFlags*/);
7950                 synchronized (mLock) {
7951                     prepareAppDataAfterInstallLIF(pkg);
7952                     try {
7953                         updateSharedLibrariesLocked(pkg, stubPkgSetting, null, null,
7954                                 Collections.unmodifiableMap(mPackages));
7955                     } catch (PackageManagerException e) {
7956                         Slog.w(TAG, "updateAllSharedLibrariesLPw failed: ", e);
7957                     }
7958                     mPermissionManager.onPackageInstalled(pkg,
7959                             PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT,
7960                             UserHandle.USER_ALL);
7961                     writeSettingsLPrTEMP();
7962                 }
7963             } catch (PackageManagerException e) {
7964                 // Whoops! Something went very wrong; roll back to the stub and disable the package
7965                 try (PackageFreezer freezer =
7966                         freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
7967                     synchronized (mLock) {
7968                         // NOTE: Ensure the system package is enabled; even for a compressed stub.
7969                         // If we don't, installing the system package fails during scan
7970                         enableSystemPackageLPw(stubPkg);
7971                     }
7972                     installPackageFromSystemLIF(stubPkg.getPath(),
7973                             mUserManager.getUserIds() /*allUserHandles*/, null /*origUserHandles*/,
7974                             true /*writeSettings*/);
7975                 } catch (PackageManagerException pme) {
7976                     // Serious WTF; we have to be able to install the stub
7977                     Slog.wtf(TAG, "Failed to restore system package:" + stubPkg.getPackageName(),
7978                             pme);
7979                 } finally {
7980                     // Disable the package; the stub by itself is not runnable
7981                     synchronized (mLock) {
7982                         final PackageSetting stubPs = mSettings.getPackageLPr(
7983                                 stubPkg.getPackageName());
7984                         if (stubPs != null) {
7985                             stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED,
7986                                     UserHandle.USER_SYSTEM, "android");
7987                         }
7988                         writeSettingsLPrTEMP();
7989                     }
7990                 }
7991                 return false;
7992             }
7993             clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
7994                     | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
7995             mDexManager.notifyPackageUpdated(pkg.getPackageName(),
7996                     pkg.getBaseApkPath(), pkg.getSplitCodePaths());
7997         }
7998         return true;
7999     }
8000 
installStubPackageLI(AndroidPackage stubPkg, @ParseFlags int parseFlags, @ScanFlags int scanFlags)8001     private AndroidPackage installStubPackageLI(AndroidPackage stubPkg,
8002             @ParseFlags int parseFlags, @ScanFlags int scanFlags)
8003                     throws PackageManagerException {
8004         if (DEBUG_COMPRESSION) {
8005             Slog.i(TAG, "Uncompressing system stub; pkg: " + stubPkg.getPackageName());
8006         }
8007         // uncompress the binary to its eventual destination on /data
8008         final File scanFile = decompressPackage(stubPkg.getPackageName(), stubPkg.getPath());
8009         if (scanFile == null) {
8010             throw new PackageManagerException(
8011                     "Unable to decompress stub at " + stubPkg.getPath());
8012         }
8013         synchronized (mLock) {
8014             mSettings.disableSystemPackageLPw(stubPkg.getPackageName(), true /*replaced*/);
8015         }
8016         removePackageLI(stubPkg, true /*chatty*/);
8017         try {
8018             return scanPackageTracedLI(scanFile, parseFlags, scanFlags, 0, null);
8019         } catch (PackageManagerException e) {
8020             Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.getPackageName(),
8021                     e);
8022             // Remove the failed install
8023             removeCodePathLI(scanFile);
8024             throw e;
8025         }
8026     }
8027 
8028     /**
8029      * Decompresses the given package on the system image onto
8030      * the /data partition.
8031      * @return The directory the package was decompressed into. Otherwise, {@code null}.
8032      */
decompressPackage(String packageName, String codePath)8033     private File decompressPackage(String packageName, String codePath) {
8034         final File[] compressedFiles = getCompressedFiles(codePath);
8035         if (compressedFiles == null || compressedFiles.length == 0) {
8036             if (DEBUG_COMPRESSION) {
8037                 Slog.i(TAG, "No files to decompress: " + codePath);
8038             }
8039             return null;
8040         }
8041         final File dstCodePath =
8042                 getNextCodePath(Environment.getDataAppDirectory(null), packageName);
8043         int ret = PackageManager.INSTALL_SUCCEEDED;
8044         try {
8045             makeDirRecursive(dstCodePath, 0755);
8046             for (File srcFile : compressedFiles) {
8047                 final String srcFileName = srcFile.getName();
8048                 final String dstFileName = srcFileName.substring(
8049                         0, srcFileName.length() - COMPRESSED_EXTENSION.length());
8050                 final File dstFile = new File(dstCodePath, dstFileName);
8051                 ret = decompressFile(srcFile, dstFile);
8052                 if (ret != PackageManager.INSTALL_SUCCEEDED) {
8053                     logCriticalInfo(Log.ERROR, "Failed to decompress"
8054                             + "; pkg: " + packageName
8055                             + ", file: " + dstFileName);
8056                     break;
8057                 }
8058             }
8059         } catch (ErrnoException e) {
8060             logCriticalInfo(Log.ERROR, "Failed to decompress"
8061                     + "; pkg: " + packageName
8062                     + ", err: " + e.errno);
8063         }
8064         if (ret == PackageManager.INSTALL_SUCCEEDED) {
8065             final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
8066             NativeLibraryHelper.Handle handle = null;
8067             try {
8068                 handle = NativeLibraryHelper.Handle.create(dstCodePath);
8069                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
8070                         null /*abiOverride*/, false /*isIncremental*/);
8071             } catch (IOException e) {
8072                 logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
8073                         + "; pkg: " + packageName);
8074                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
8075             } finally {
8076                 IoUtils.closeQuietly(handle);
8077             }
8078         }
8079         if (ret == PackageManager.INSTALL_SUCCEEDED) {
8080             // NOTE: During boot, we have to delay releasing cblocks for no other reason than
8081             // we cannot retrieve the setting {@link Secure#RELEASE_COMPRESS_BLOCKS_ON_INSTALL}.
8082             // When we no longer need to read that setting, cblock release can occur always
8083             // occur here directly
8084             if (!mSystemReady) {
8085                 if (mReleaseOnSystemReady == null) {
8086                     mReleaseOnSystemReady = new ArrayList<>();
8087                 }
8088                 mReleaseOnSystemReady.add(dstCodePath);
8089             } else {
8090                 final ContentResolver resolver = mContext.getContentResolver();
8091                 F2fsUtils.releaseCompressedBlocks(resolver, dstCodePath);
8092             }
8093         }
8094         if (ret != PackageManager.INSTALL_SUCCEEDED) {
8095             if (!dstCodePath.exists()) {
8096                 return null;
8097             }
8098             removeCodePathLI(dstCodePath);
8099             return null;
8100         }
8101 
8102         return dstCodePath;
8103     }
8104 
8105     @GuardedBy("mLock")
updateInstantAppInstallerLocked(String modifiedPackage)8106     private void updateInstantAppInstallerLocked(String modifiedPackage) {
8107         // we're only interested in updating the installer appliction when 1) it's not
8108         // already set or 2) the modified package is the installer
8109         if (mInstantAppInstallerActivity != null
8110                 && !mInstantAppInstallerActivity.getComponentName().getPackageName()
8111                         .equals(modifiedPackage)) {
8112             return;
8113         }
8114         setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
8115     }
8116 
preparePackageParserCache(boolean forEngBuild)8117     private @Nullable File preparePackageParserCache(boolean forEngBuild) {
8118         if (!FORCE_PACKAGE_PARSED_CACHE_ENABLED) {
8119             if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
8120                 return null;
8121             }
8122 
8123             // Disable package parsing on eng builds to allow for faster incremental development.
8124             if (forEngBuild) {
8125                 return null;
8126             }
8127 
8128             if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
8129                 Slog.i(TAG, "Disabling package parser cache due to system property.");
8130                 return null;
8131             }
8132         }
8133 
8134         // The base directory for the package parser cache lives under /data/system/.
8135         final File cacheBaseDir = Environment.getPackageCacheDirectory();
8136         if (!FileUtils.createDir(cacheBaseDir)) {
8137             return null;
8138         }
8139 
8140         // There are several items that need to be combined together to safely
8141         // identify cached items. In particular, changing the value of certain
8142         // feature flags should cause us to invalidate any caches.
8143         final String cacheName = FORCE_PACKAGE_PARSED_CACHE_ENABLED ? "debug"
8144                 : SystemProperties.digestOf("ro.build.fingerprint");
8145 
8146         // Reconcile cache directories, keeping only what we'd actually use.
8147         for (File cacheDir : FileUtils.listFilesOrEmpty(cacheBaseDir)) {
8148             if (Objects.equals(cacheName, cacheDir.getName())) {
8149                 Slog.d(TAG, "Keeping known cache " + cacheDir.getName());
8150             } else {
8151                 Slog.d(TAG, "Destroying unknown cache " + cacheDir.getName());
8152                 FileUtils.deleteContentsAndDir(cacheDir);
8153             }
8154         }
8155 
8156         // Return the versioned package cache directory.
8157         File cacheDir = FileUtils.createDir(cacheBaseDir, cacheName);
8158 
8159         if (cacheDir == null) {
8160             // Something went wrong. Attempt to delete everything and return.
8161             Slog.wtf(TAG, "Cache directory cannot be created - wiping base dir " + cacheBaseDir);
8162             FileUtils.deleteContentsAndDir(cacheBaseDir);
8163             return null;
8164         }
8165 
8166         // The following is a workaround to aid development on non-numbered userdebug
8167         // builds or cases where "adb sync" is used on userdebug builds. If we detect that
8168         // the system partition is newer.
8169         //
8170         // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
8171         // that starts with "eng." to signify that this is an engineering build and not
8172         // destined for release.
8173         if (mIsUserDebugBuild && mIncrementalVersion.startsWith("eng.")) {
8174             Slog.w(TAG, "Wiping cache directory because the system partition changed.");
8175 
8176             // Heuristic: If the /system directory has been modified recently due to an "adb sync"
8177             // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
8178             // in general and should not be used for production changes. In this specific case,
8179             // we know that they will work.
8180             File frameworkDir =
8181                     new File(Environment.getRootDirectory(), "framework");
8182             if (cacheDir.lastModified() < frameworkDir.lastModified()) {
8183                 FileUtils.deleteContents(cacheBaseDir);
8184                 cacheDir = FileUtils.createDir(cacheBaseDir, cacheName);
8185             }
8186         }
8187 
8188         return cacheDir;
8189     }
8190 
8191     @Override
isFirstBoot()8192     public boolean isFirstBoot() {
8193         // allow instant applications
8194         return mFirstBoot;
8195     }
8196 
8197     @Override
isOnlyCoreApps()8198     public boolean isOnlyCoreApps() {
8199         // allow instant applications
8200         return mOnlyCore;
8201     }
8202 
8203     @Override
isDeviceUpgrading()8204     public boolean isDeviceUpgrading() {
8205         // allow instant applications
8206         // The system property allows testing ota flow when upgraded to the same image.
8207         return mIsUpgrade || SystemProperties.getBoolean(
8208                 "persist.pm.mock-upgrade", false /* default */);
8209     }
8210 
getRequiredButNotReallyRequiredVerifierLPr()8211     private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
8212         final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
8213 
8214         final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
8215                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
8216                 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
8217         if (matches.size() == 1) {
8218             return matches.get(0).getComponentInfo().packageName;
8219         } else if (matches.size() == 0) {
8220             Log.w(TAG, "There should probably be a verifier, but, none were found");
8221             return null;
8222         }
8223         throw new RuntimeException("There must be exactly one verifier; found " + matches);
8224     }
8225 
getRequiredSharedLibraryLPr(String name, int version)8226     private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
8227         synchronized (mLock) {
8228             SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(name, version);
8229             if (libraryInfo == null) {
8230                 throw new IllegalStateException("Missing required shared library:" + name);
8231             }
8232             String packageName = libraryInfo.getPackageName();
8233             if (packageName == null) {
8234                 throw new IllegalStateException("Expected a package for shared library " + name);
8235             }
8236             return packageName;
8237         }
8238     }
8239 
8240     @NonNull
getRequiredServicesExtensionPackageLPr()8241     private String getRequiredServicesExtensionPackageLPr() {
8242         String servicesExtensionPackage =
8243                 ensureSystemPackageName(
8244                         mContext.getString(R.string.config_servicesExtensionPackage));
8245         if (TextUtils.isEmpty(servicesExtensionPackage)) {
8246             throw new RuntimeException(
8247                     "Required services extension package is missing, check "
8248                             + "config_servicesExtensionPackage.");
8249         }
8250         return servicesExtensionPackage;
8251     }
8252 
getRequiredInstallerLPr()8253     private @NonNull String getRequiredInstallerLPr() {
8254         final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
8255         intent.addCategory(Intent.CATEGORY_DEFAULT);
8256         intent.setDataAndType(Uri.parse("content://com.example/foo.apk"), PACKAGE_MIME_TYPE);
8257 
8258         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
8259                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
8260                 UserHandle.USER_SYSTEM);
8261         if (matches.size() == 1) {
8262             ResolveInfo resolveInfo = matches.get(0);
8263             if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
8264                 throw new RuntimeException("The installer must be a privileged app");
8265             }
8266             return matches.get(0).getComponentInfo().packageName;
8267         } else {
8268             throw new RuntimeException("There must be exactly one installer; found " + matches);
8269         }
8270     }
8271 
getRequiredUninstallerLPr()8272     private @NonNull String getRequiredUninstallerLPr() {
8273         final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
8274         intent.addCategory(Intent.CATEGORY_DEFAULT);
8275         intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
8276 
8277         final ResolveInfo resolveInfo = resolveIntent(intent, null,
8278                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
8279                 UserHandle.USER_SYSTEM);
8280         if (resolveInfo == null ||
8281                 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
8282             throw new RuntimeException("There must be exactly one uninstaller; found "
8283                     + resolveInfo);
8284         }
8285         return resolveInfo.getComponentInfo().packageName;
8286     }
8287 
getRequiredPermissionControllerLPr()8288     private @NonNull String getRequiredPermissionControllerLPr() {
8289         final Intent intent = new Intent(Intent.ACTION_MANAGE_PERMISSIONS);
8290         intent.addCategory(Intent.CATEGORY_DEFAULT);
8291 
8292         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
8293                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
8294                 UserHandle.USER_SYSTEM);
8295         if (matches.size() == 1) {
8296             ResolveInfo resolveInfo = matches.get(0);
8297             if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
8298                 throw new RuntimeException("The permissions manager must be a privileged app");
8299             }
8300             return matches.get(0).getComponentInfo().packageName;
8301         } else {
8302             throw new RuntimeException("There must be exactly one permissions manager; found "
8303                     + matches);
8304         }
8305     }
8306 
getIntentFilterVerifierComponentNameLPr()8307     private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
8308         final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
8309 
8310         final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
8311                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
8312                 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
8313         ResolveInfo best = null;
8314         final int N = matches.size();
8315         for (int i = 0; i < N; i++) {
8316             final ResolveInfo cur = matches.get(i);
8317             final String packageName = cur.getComponentInfo().packageName;
8318             if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
8319                     packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
8320                 continue;
8321             }
8322 
8323             if (best == null || cur.priority > best.priority) {
8324                 best = cur;
8325             }
8326         }
8327 
8328         if (best != null) {
8329             return best.getComponentInfo().getComponentName();
8330         }
8331         Slog.w(TAG, "Intent filter verifier not found");
8332         return null;
8333     }
8334 
8335     @Nullable
getDomainVerificationAgentComponentNameLPr()8336     private ComponentName getDomainVerificationAgentComponentNameLPr() {
8337         Intent intent = new Intent(Intent.ACTION_DOMAINS_NEED_VERIFICATION);
8338         List<ResolveInfo> matches = queryIntentReceiversInternal(intent, null,
8339                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
8340                 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
8341         ResolveInfo best = null;
8342         final int N = matches.size();
8343         for (int i = 0; i < N; i++) {
8344             final ResolveInfo cur = matches.get(i);
8345             final String packageName = cur.getComponentInfo().packageName;
8346             if (checkPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT,
8347                     packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
8348                 Slog.w(TAG, "Domain verification agent found but does not hold permission: "
8349                         + packageName);
8350                 continue;
8351             }
8352 
8353             if (best == null || cur.priority > best.priority) {
8354                 if (isComponentEffectivelyEnabled(cur.getComponentInfo(), UserHandle.USER_SYSTEM)) {
8355                     best = cur;
8356                 } else {
8357                     Slog.w(TAG, "Domain verification agent found but not enabled");
8358                 }
8359             }
8360         }
8361 
8362         if (best != null) {
8363             return best.getComponentInfo().getComponentName();
8364         }
8365         Slog.w(TAG, "Domain verification agent not found");
8366         return null;
8367     }
8368 
8369     @Override
getInstantAppResolverComponent()8370     public @Nullable ComponentName getInstantAppResolverComponent() {
8371         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8372             return null;
8373         }
8374         synchronized (mLock) {
8375             final ComponentName instantAppResolver = getInstantAppResolverLPr();
8376             if (instantAppResolver == null) {
8377                 return null;
8378             }
8379             return instantAppResolver;
8380         }
8381     }
8382 
getInstantAppResolverLPr()8383     private @Nullable ComponentName getInstantAppResolverLPr() {
8384         final String[] packageArray =
8385                 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
8386         if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
8387             if (DEBUG_INSTANT) {
8388                 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
8389             }
8390             return null;
8391         }
8392 
8393         final int callingUid = Binder.getCallingUid();
8394         final int resolveFlags =
8395                 MATCH_DIRECT_BOOT_AWARE
8396                 | MATCH_DIRECT_BOOT_UNAWARE
8397                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
8398         final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE);
8399         List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
8400                 resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
8401         final int N = resolvers.size();
8402         if (N == 0) {
8403             if (DEBUG_INSTANT) {
8404                 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
8405             }
8406             return null;
8407         }
8408 
8409         final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
8410         for (int i = 0; i < N; i++) {
8411             final ResolveInfo info = resolvers.get(i);
8412 
8413             if (info.serviceInfo == null) {
8414                 continue;
8415             }
8416 
8417             final String packageName = info.serviceInfo.packageName;
8418             if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
8419                 if (DEBUG_INSTANT) {
8420                     Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
8421                             + " pkg: " + packageName + ", info:" + info);
8422                 }
8423                 continue;
8424             }
8425 
8426             if (DEBUG_INSTANT) {
8427                 Slog.v(TAG, "Ephemeral resolver found;"
8428                         + " pkg: " + packageName + ", info:" + info);
8429             }
8430             return new ComponentName(packageName, info.serviceInfo.name);
8431         }
8432         if (DEBUG_INSTANT) {
8433             Slog.v(TAG, "Ephemeral resolver NOT found");
8434         }
8435         return null;
8436     }
8437 
8438     @GuardedBy("mLock")
getInstantAppInstallerLPr()8439     private @Nullable ActivityInfo getInstantAppInstallerLPr() {
8440         String[] orderedActions = mIsEngBuild
8441                 ? new String[]{
8442                         Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE + "_TEST",
8443                         Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE}
8444                 : new String[]{
8445                         Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE};
8446 
8447         final int resolveFlags =
8448                 MATCH_DIRECT_BOOT_AWARE
8449                         | MATCH_DIRECT_BOOT_UNAWARE
8450                         | Intent.FLAG_IGNORE_EPHEMERAL
8451                         | (mIsEngBuild ? 0 : MATCH_SYSTEM_ONLY);
8452         final Intent intent = new Intent();
8453         intent.addCategory(Intent.CATEGORY_DEFAULT);
8454         intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
8455         List<ResolveInfo> matches = null;
8456         for (String action : orderedActions) {
8457             intent.setAction(action);
8458             matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
8459                     resolveFlags, UserHandle.USER_SYSTEM);
8460             if (matches.isEmpty()) {
8461                 if (DEBUG_INSTANT) {
8462                     Slog.d(TAG, "Instant App installer not found with " + action);
8463                 }
8464             } else {
8465                 break;
8466             }
8467         }
8468         Iterator<ResolveInfo> iter = matches.iterator();
8469         while (iter.hasNext()) {
8470             final ResolveInfo rInfo = iter.next();
8471             if (checkPermission(
8472                     Manifest.permission.INSTALL_PACKAGES,
8473                     rInfo.activityInfo.packageName, 0) == PERMISSION_GRANTED || mIsEngBuild) {
8474                 continue;
8475             }
8476             iter.remove();
8477         }
8478         if (matches.size() == 0) {
8479             return null;
8480         } else if (matches.size() == 1) {
8481             return (ActivityInfo) matches.get(0).getComponentInfo();
8482         } else {
8483             throw new RuntimeException(
8484                     "There must be at most one ephemeral installer; found " + matches);
8485         }
8486     }
8487 
getInstantAppResolverSettingsLPr( @onNull ComponentName resolver)8488     private @Nullable ComponentName getInstantAppResolverSettingsLPr(
8489             @NonNull ComponentName resolver) {
8490         final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
8491                 .addCategory(Intent.CATEGORY_DEFAULT)
8492                 .setPackage(resolver.getPackageName());
8493         final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
8494         List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
8495                 UserHandle.USER_SYSTEM);
8496         if (matches.isEmpty()) {
8497             return null;
8498         }
8499         return matches.get(0).getComponentInfo().getComponentName();
8500     }
8501 
8502     @Override
onTransact(int code, Parcel data, Parcel reply, int flags)8503     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
8504             throws RemoteException {
8505         try {
8506             return super.onTransact(code, data, reply, flags);
8507         } catch (RuntimeException e) {
8508             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
8509                 Slog.wtf(TAG, "Package Manager Crash", e);
8510             }
8511             throw e;
8512         }
8513     }
8514 
8515     /**
8516      * Returns whether or not a full application can see an instant application.
8517      * <p>
8518      * Currently, there are four cases in which this can occur:
8519      * <ol>
8520      * <li>The calling application is a "special" process. Special processes
8521      *     are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
8522      * <li>The calling application has the permission
8523      *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
8524      * <li>The calling application is the default launcher on the
8525      *     system partition.</li>
8526      * <li>The calling application is the default app prediction service.</li>
8527      * </ol>
8528      */
canViewInstantApps(int callingUid, int userId)8529     private boolean canViewInstantApps(int callingUid, int userId) {
8530         return mComputer.canViewInstantApps(callingUid, userId);
8531     }
8532 
generatePackageInfo(PackageSetting ps, int flags, int userId)8533     private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
8534         return mComputer.generatePackageInfo(ps, flags, userId);
8535     }
8536 
8537     @Override
checkPackageStartable(String packageName, int userId)8538     public void checkPackageStartable(String packageName, int userId) {
8539         final int callingUid = Binder.getCallingUid();
8540         if (getInstantAppPackageName(callingUid) != null) {
8541             throw new SecurityException("Instant applications don't have access to this method");
8542         }
8543         if (!mUserManager.exists(userId)) {
8544             throw new SecurityException("User doesn't exist");
8545         }
8546         enforceCrossUserPermission(callingUid, userId, false, false, "checkPackageStartable");
8547         switch (getPackageStartability(packageName, callingUid, userId)) {
8548             case PACKAGE_STARTABILITY_NOT_FOUND:
8549                 throw new SecurityException("Package " + packageName + " was not found!");
8550             case PACKAGE_STARTABILITY_NOT_SYSTEM:
8551                 throw new SecurityException("Package " + packageName + " not a system app!");
8552             case PACKAGE_STARTABILITY_FROZEN:
8553                 throw new SecurityException("Package " + packageName + " is currently frozen!");
8554             case PACKAGE_STARTABILITY_DIRECT_BOOT_UNSUPPORTED:
8555                 throw new SecurityException("Package " + packageName + " is not encryption aware!");
8556             case PACKAGE_STARTABILITY_OK:
8557             default:
8558                 return;
8559         }
8560     }
8561 
getPackageStartability(String packageName, int callingUid, int userId)8562     private @PackageStartability int getPackageStartability(String packageName,
8563             int callingUid, int userId) {
8564         final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
8565         synchronized (mLock) {
8566             final PackageSetting ps = mSettings.getPackageLPr(packageName);
8567             if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)
8568                     || !ps.getInstalled(userId)) {
8569                 return PACKAGE_STARTABILITY_NOT_FOUND;
8570             }
8571 
8572             if (mSafeMode && !ps.isSystem()) {
8573                 return PACKAGE_STARTABILITY_NOT_SYSTEM;
8574             }
8575 
8576             if (mFrozenPackages.contains(packageName)) {
8577                 return PACKAGE_STARTABILITY_FROZEN;
8578             }
8579 
8580             if (!userKeyUnlocked && !AndroidPackageUtils.isEncryptionAware(ps.pkg)) {
8581                 return PACKAGE_STARTABILITY_DIRECT_BOOT_UNSUPPORTED;
8582             }
8583         }
8584         return PACKAGE_STARTABILITY_OK;
8585     }
8586 
8587     @Override
isPackageAvailable(String packageName, int userId)8588     public boolean isPackageAvailable(String packageName, int userId) {
8589         if (!mUserManager.exists(userId)) return false;
8590         final int callingUid = Binder.getCallingUid();
8591         enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
8592                 false /*checkShell*/, "is package available");
8593         synchronized (mLock) {
8594             AndroidPackage p = mPackages.get(packageName);
8595             if (p != null) {
8596                 final PackageSetting ps = getPackageSetting(p.getPackageName());
8597                 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
8598                     return false;
8599                 }
8600                 if (ps != null) {
8601                     final PackageUserState state = ps.readUserState(userId);
8602                     if (state != null) {
8603                         return PackageParser.isAvailable(state);
8604                     }
8605                 }
8606             }
8607         }
8608         return false;
8609     }
8610 
8611     @Override
getPackageInfo(String packageName, int flags, int userId)8612     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
8613         return mComputer.getPackageInfo(packageName, flags, userId);
8614     }
8615 
8616     @Override
getPackageInfoVersioned(VersionedPackage versionedPackage, int flags, int userId)8617     public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
8618             int flags, int userId) {
8619         return getPackageInfoInternal(versionedPackage.getPackageName(),
8620                 versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
8621     }
8622 
8623     /**
8624      * Important: The provided filterCallingUid is used exclusively to filter out packages
8625      * that can be seen based on user state. It's typically the original caller uid prior
8626      * to clearing. Because it can only be provided by trusted code, its value can be
8627      * trusted and will be used as-is; unlike userId which will be validated by this method.
8628      */
getPackageInfoInternal(String packageName, long versionCode, int flags, int filterCallingUid, int userId)8629     private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
8630             int flags, int filterCallingUid, int userId) {
8631         return mComputer.getPackageInfoInternal(packageName, versionCode,
8632                 flags, filterCallingUid, userId);
8633     }
8634 
isComponentVisibleToInstantApp(@ullable ComponentName component)8635     private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
8636         return mComputer.isComponentVisibleToInstantApp(component);
8637     }
8638 
isComponentVisibleToInstantApp( @ullable ComponentName component, @ComponentType int type)8639     private boolean isComponentVisibleToInstantApp(
8640             @Nullable ComponentName component, @ComponentType int type) {
8641         return mComputer.isComponentVisibleToInstantApp(
8642             component, type);
8643     }
8644 
8645     /**
8646      * Returns whether or not access to the application should be filtered.
8647      * <p>
8648      * Access may be limited based upon whether the calling or target applications
8649      * are instant applications.
8650      *
8651      * @see #canViewInstantApps(int, int)
8652      */
8653     @GuardedBy("mLock")
shouldFilterApplicationLocked(@ullable PackageSetting ps, int callingUid, @Nullable ComponentName component, @ComponentType int componentType, int userId)8654     private boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid,
8655             @Nullable ComponentName component, @ComponentType int componentType, int userId) {
8656         return mComputer.shouldFilterApplicationLocked(ps, callingUid,
8657                 component, componentType, userId);
8658     }
8659 
8660     /**
8661      * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
8662      */
8663     @GuardedBy("mLock")
shouldFilterApplicationLocked( @ullable PackageSetting ps, int callingUid, int userId)8664     private boolean shouldFilterApplicationLocked(
8665             @Nullable PackageSetting ps, int callingUid, int userId) {
8666         return mComputer.shouldFilterApplicationLocked(
8667             ps, callingUid, userId);
8668     }
8669 
8670     /**
8671      * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
8672      */
8673     @GuardedBy("mLock")
shouldFilterApplicationLocked(@onNull SharedUserSetting sus, int callingUid, int userId)8674     private boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus, int callingUid,
8675             int userId) {
8676         return mComputer.shouldFilterApplicationLocked(sus, callingUid, userId);
8677     }
8678 
8679     @GuardedBy("mLock")
filterSharedLibPackageLPr(@ullable PackageSetting ps, int uid, int userId, int flags)8680     private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
8681             int flags) {
8682         return mComputer.filterSharedLibPackageLPr(ps, uid, userId,
8683                 flags);
8684     }
8685 
8686     @Override
currentToCanonicalPackageNames(String[] names)8687     public String[] currentToCanonicalPackageNames(String[] names) {
8688         final int callingUid = Binder.getCallingUid();
8689         if (getInstantAppPackageName(callingUid) != null) {
8690             return names;
8691         }
8692         final String[] out = new String[names.length];
8693         // reader
8694         synchronized (mLock) {
8695             final int callingUserId = UserHandle.getUserId(callingUid);
8696             final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
8697             for (int i=names.length-1; i>=0; i--) {
8698                 final PackageSetting ps = mSettings.getPackageLPr(names[i]);
8699                 boolean translateName = false;
8700                 if (ps != null && ps.realName != null) {
8701                     final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
8702                     translateName = !targetIsInstantApp
8703                             || canViewInstantApps
8704                             || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
8705                                     UserHandle.getAppId(callingUid), ps.appId);
8706                 }
8707                 out[i] = translateName ? ps.realName : names[i];
8708             }
8709         }
8710         return out;
8711     }
8712 
8713     @Override
canonicalToCurrentPackageNames(String[] names)8714     public String[] canonicalToCurrentPackageNames(String[] names) {
8715         final int callingUid = Binder.getCallingUid();
8716         if (getInstantAppPackageName(callingUid) != null) {
8717             return names;
8718         }
8719         final String[] out = new String[names.length];
8720         // reader
8721         synchronized (mLock) {
8722             final int callingUserId = UserHandle.getUserId(callingUid);
8723             final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
8724             for (int i=names.length-1; i>=0; i--) {
8725                 final String cur = mSettings.getRenamedPackageLPr(names[i]);
8726                 boolean translateName = false;
8727                 if (cur != null) {
8728                     final PackageSetting ps = mSettings.getPackageLPr(names[i]);
8729                     final boolean targetIsInstantApp =
8730                             ps != null && ps.getInstantApp(callingUserId);
8731                     translateName = !targetIsInstantApp
8732                             || canViewInstantApps
8733                             || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
8734                                     UserHandle.getAppId(callingUid), ps.appId);
8735                 }
8736                 out[i] = translateName ? cur : names[i];
8737             }
8738         }
8739         return out;
8740     }
8741 
8742     @Override
getPackageUid(String packageName, int flags, int userId)8743     public int getPackageUid(String packageName, int flags, int userId) {
8744         if (!mUserManager.exists(userId)) return -1;
8745         final int callingUid = Binder.getCallingUid();
8746         flags = updateFlagsForPackage(flags, userId);
8747         enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
8748                 false /*checkShell*/, "getPackageUid");
8749         return getPackageUidInternal(packageName, flags, userId, callingUid);
8750     }
8751 
getPackageUidInternal(String packageName, int flags, int userId, int callingUid)8752     private int getPackageUidInternal(String packageName, int flags, int userId, int callingUid) {
8753         return mComputer.getPackageUidInternal(packageName, flags, userId, callingUid);
8754     }
8755 
8756     @Override
getPackageGids(String packageName, int flags, int userId)8757     public int[] getPackageGids(String packageName, int flags, int userId) {
8758         if (!mUserManager.exists(userId)) return null;
8759         final int callingUid = Binder.getCallingUid();
8760         flags = updateFlagsForPackage(flags, userId);
8761         enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
8762                 false /*checkShell*/, "getPackageGids");
8763 
8764         // reader
8765         synchronized (mLock) {
8766             final AndroidPackage p = mPackages.get(packageName);
8767             if (p != null && AndroidPackageUtils.isMatchForSystemOnly(p, flags)) {
8768                 PackageSetting ps = getPackageSetting(p.getPackageName());
8769                 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
8770                     return null;
8771                 }
8772                 // TODO: Shouldn't this be checking for package installed state for userId and
8773                 // return null?
8774                 return mPermissionManager.getGidsForUid(UserHandle.getUid(userId, ps.appId));
8775             }
8776             if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
8777                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
8778                 if (ps != null && ps.isMatch(flags)
8779                         && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
8780                     return mPermissionManager.getGidsForUid(UserHandle.getUid(userId, ps.appId));
8781                 }
8782             }
8783         }
8784 
8785         return null;
8786     }
8787 
8788     // NOTE: Can't remove due to unsupported app usage
8789     @Override
getPermissionGroupInfo(String groupName, int flags)8790     public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
8791         // Because this is accessed via the package manager service AIDL,
8792         // go through the permission manager service AIDL
8793         return mContext.getSystemService(PermissionManager.class)
8794                 .getPermissionGroupInfo(groupName, flags);
8795     }
8796 
8797     @GuardedBy("mLock")
generateApplicationInfoFromSettingsLPw(String packageName, int flags, int filterCallingUid, int userId)8798     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
8799             int filterCallingUid, int userId) {
8800         return mComputer.generateApplicationInfoFromSettingsLPw(packageName, flags,
8801                 filterCallingUid, userId);
8802     }
8803 
8804     @Override
getApplicationInfo(String packageName, int flags, int userId)8805     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
8806         return mComputer.getApplicationInfo(packageName, flags, userId);
8807     }
8808 
8809     /**
8810      * Important: The provided filterCallingUid is used exclusively to filter out applications
8811      * that can be seen based on user state. It's typically the original caller uid prior
8812      * to clearing. Because it can only be provided by trusted code, its value can be
8813      * trusted and will be used as-is; unlike userId which will be validated by this method.
8814      */
getApplicationInfoInternal(String packageName, int flags, int filterCallingUid, int userId)8815     private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
8816             int filterCallingUid, int userId) {
8817         return mComputer.getApplicationInfoInternal(packageName, flags,
8818                 filterCallingUid, userId);
8819     }
8820 
8821     @GuardedBy("mLock")
normalizePackageNameLPr(String packageName)8822     private String normalizePackageNameLPr(String packageName) {
8823         String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
8824         return normalizedPackageName != null ? normalizedPackageName : packageName;
8825     }
8826 
8827     @Override
deletePreloadsFileCache()8828     public void deletePreloadsFileCache() {
8829         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CLEAR_APP_CACHE,
8830                 "deletePreloadsFileCache");
8831         File dir = Environment.getDataPreloadsFileCacheDirectory();
8832         Slog.i(TAG, "Deleting preloaded file cache " + dir);
8833         FileUtils.deleteContents(dir);
8834     }
8835 
8836     @Override
freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, final int storageFlags, final IPackageDataObserver observer)8837     public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
8838             final int storageFlags, final IPackageDataObserver observer) {
8839         mContext.enforceCallingOrSelfPermission(
8840                 android.Manifest.permission.CLEAR_APP_CACHE, null);
8841         mHandler.post(() -> {
8842             boolean success = false;
8843             try {
8844                 freeStorage(volumeUuid, freeStorageSize, storageFlags);
8845                 success = true;
8846             } catch (IOException e) {
8847                 Slog.w(TAG, e);
8848             }
8849             if (observer != null) {
8850                 try {
8851                     observer.onRemoveCompleted(null, success);
8852                 } catch (RemoteException e) {
8853                     Slog.w(TAG, e);
8854                 }
8855             }
8856         });
8857     }
8858 
8859     @Override
freeStorage(final String volumeUuid, final long freeStorageSize, final int storageFlags, final IntentSender pi)8860     public void freeStorage(final String volumeUuid, final long freeStorageSize,
8861             final int storageFlags, final IntentSender pi) {
8862         mContext.enforceCallingOrSelfPermission(
8863                 android.Manifest.permission.CLEAR_APP_CACHE, TAG);
8864         mHandler.post(() -> {
8865             boolean success = false;
8866             try {
8867                 freeStorage(volumeUuid, freeStorageSize, storageFlags);
8868                 success = true;
8869             } catch (IOException e) {
8870                 Slog.w(TAG, e);
8871             }
8872             if (pi != null) {
8873                 try {
8874                     pi.sendIntent(null, success ? 1 : 0, null, null, null);
8875                 } catch (SendIntentException e) {
8876                     Slog.w(TAG, e);
8877                 }
8878             }
8879         });
8880     }
8881 
8882     /**
8883      * Blocking call to clear various types of cached data across the system
8884      * until the requested bytes are available.
8885      */
freeStorage(String volumeUuid, long bytes, int storageFlags)8886     public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
8887         final StorageManager storage = mInjector.getSystemService(StorageManager.class);
8888         final File file = storage.findPathForUuid(volumeUuid);
8889         if (file.getUsableSpace() >= bytes) return;
8890 
8891         if (mEnableFreeCacheV2) {
8892             final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
8893                     volumeUuid);
8894             final boolean aggressive = (storageFlags
8895                     & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
8896             final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
8897 
8898             // 1. Pre-flight to determine if we have any chance to succeed
8899             // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
8900             if (internalVolume && (aggressive || SystemProperties
8901                     .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
8902                 deletePreloadsFileCache();
8903                 if (file.getUsableSpace() >= bytes) return;
8904             }
8905 
8906             // 3. Consider parsed APK data (aggressive only)
8907             if (internalVolume && aggressive) {
8908                 FileUtils.deleteContents(mCacheDir);
8909                 if (file.getUsableSpace() >= bytes) return;
8910             }
8911 
8912             // 4. Consider cached app data (above quotas)
8913             try {
8914                 mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
8915                         Installer.FLAG_FREE_CACHE_V2);
8916             } catch (InstallerException ignored) {
8917             }
8918             if (file.getUsableSpace() >= bytes) return;
8919 
8920             // 5. Consider shared libraries with refcount=0 and age>min cache period
8921             if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
8922                     android.provider.Settings.Global.getLong(mContext.getContentResolver(),
8923                             Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
8924                             DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
8925                 return;
8926             }
8927 
8928             // 6. Consider dexopt output (aggressive only)
8929             // TODO: Implement
8930 
8931             // 7. Consider installed instant apps unused longer than min cache period
8932             if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
8933                     android.provider.Settings.Global.getLong(mContext.getContentResolver(),
8934                             Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
8935                             InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
8936                 return;
8937             }
8938 
8939             // 8. Consider cached app data (below quotas)
8940             try {
8941                 mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
8942                         Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
8943             } catch (InstallerException ignored) {
8944             }
8945             if (file.getUsableSpace() >= bytes) return;
8946 
8947             // 9. Consider DropBox entries
8948             // TODO: Implement
8949 
8950             // 10. Consider instant meta-data (uninstalled apps) older that min cache period
8951             if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
8952                     android.provider.Settings.Global.getLong(mContext.getContentResolver(),
8953                             Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
8954                             InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
8955                 return;
8956             }
8957 
8958             // 11. Free storage service cache
8959             StorageManagerInternal smInternal =
8960                     mInjector.getLocalService(StorageManagerInternal.class);
8961             long freeBytesRequired = bytes - file.getUsableSpace();
8962             if (freeBytesRequired > 0) {
8963                 smInternal.freeCache(volumeUuid, freeBytesRequired);
8964             }
8965             if (file.getUsableSpace() >= bytes) return;
8966         } else {
8967             try {
8968                 mInstaller.freeCache(volumeUuid, bytes, 0, 0);
8969             } catch (InstallerException ignored) {
8970             }
8971             if (file.getUsableSpace() >= bytes) return;
8972         }
8973 
8974         throw new IOException("Failed to free " + bytes + " on storage device at " + file);
8975     }
8976 
pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)8977     private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
8978             throws IOException {
8979         final StorageManager storage = mInjector.getSystemService(StorageManager.class);
8980         final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
8981 
8982         List<VersionedPackage> packagesToDelete = null;
8983         final long now = System.currentTimeMillis();
8984 
8985         synchronized (mLock) {
8986             final int[] allUsers = mUserManager.getUserIds();
8987             final int libCount = mSharedLibraries.size();
8988             for (int i = 0; i < libCount; i++) {
8989                 final WatchedLongSparseArray<SharedLibraryInfo> versionedLib
8990                         = mSharedLibraries.valueAt(i);
8991                 if (versionedLib == null) {
8992                     continue;
8993                 }
8994                 final int versionCount = versionedLib.size();
8995                 for (int j = 0; j < versionCount; j++) {
8996                     SharedLibraryInfo libInfo = versionedLib.valueAt(j);
8997                     // Skip packages that are not static shared libs.
8998                     if (!libInfo.isStatic()) {
8999                         break;
9000                     }
9001                     // Important: We skip static shared libs used for some user since
9002                     // in such a case we need to keep the APK on the device. The check for
9003                     // a lib being used for any user is performed by the uninstall call.
9004                     final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
9005                     // Resolve the package name - we use synthetic package names internally
9006                     final String internalPackageName = resolveInternalPackageNameLPr(
9007                             declaringPackage.getPackageName(),
9008                             declaringPackage.getLongVersionCode());
9009                     final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
9010                     // Skip unused static shared libs cached less than the min period
9011                     // to prevent pruning a lib needed by a subsequently installed package.
9012                     if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
9013                         continue;
9014                     }
9015 
9016                     if (ps.pkg.isSystem()) {
9017                         continue;
9018                     }
9019 
9020                     if (packagesToDelete == null) {
9021                         packagesToDelete = new ArrayList<>();
9022                     }
9023                     packagesToDelete.add(new VersionedPackage(internalPackageName,
9024                             declaringPackage.getLongVersionCode()));
9025                 }
9026             }
9027         }
9028 
9029         if (packagesToDelete != null) {
9030             final int packageCount = packagesToDelete.size();
9031             for (int i = 0; i < packageCount; i++) {
9032                 final VersionedPackage pkgToDelete = packagesToDelete.get(i);
9033                 // Delete the package synchronously (will fail of the lib used for any user).
9034                 if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getLongVersionCode(),
9035                         UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS,
9036                         true /*removedBySystem*/) == PackageManager.DELETE_SUCCEEDED) {
9037                     if (volume.getUsableSpace() >= neededSpace) {
9038                         return true;
9039                     }
9040                 }
9041             }
9042         }
9043 
9044         return false;
9045     }
9046 
9047     /**
9048      * Update given flags when being used to request {@link PackageInfo}.
9049      */
updateFlagsForPackage(int flags, int userId)9050     private int updateFlagsForPackage(int flags, int userId) {
9051         return mComputer.updateFlagsForPackage(flags, userId);
9052     }
9053 
9054     /**
9055      * Update given flags when being used to request {@link ApplicationInfo}.
9056      */
updateFlagsForApplication(int flags, int userId)9057     private int updateFlagsForApplication(int flags, int userId) {
9058         return mComputer.updateFlagsForApplication(flags, userId);
9059     }
9060 
9061     /**
9062      * Update given flags when being used to request {@link ComponentInfo}.
9063      */
updateFlagsForComponent(int flags, int userId)9064     private int updateFlagsForComponent(int flags, int userId) {
9065         return mComputer.updateFlagsForComponent(flags, userId);
9066     }
9067 
9068     /**
9069      * Update given intent when being used to request {@link ResolveInfo}.
9070      */
updateIntentForResolve(Intent intent)9071     private Intent updateIntentForResolve(Intent intent) {
9072         if (intent.getSelector() != null) {
9073             intent = intent.getSelector();
9074         }
9075         if (DEBUG_PREFERRED) {
9076             intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
9077         }
9078         return intent;
9079     }
9080 
9081     /**
9082      * Update given flags when being used to request {@link ResolveInfo}.
9083      * <p>Instant apps are resolved specially, depending upon context. Minimally,
9084      * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
9085      * flag set. However, this flag is only honoured in three circumstances:
9086      * <ul>
9087      * <li>when called from a system process</li>
9088      * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
9089      * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
9090      * action and a {@code android.intent.category.BROWSABLE} category</li>
9091      * </ul>
9092      */
updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc)9093     private int updateFlagsForResolve(int flags, int userId, int callingUid,
9094             boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
9095         return mComputer.updateFlagsForResolve(flags, userId, callingUid,
9096                 wantInstantApps, isImplicitImageCaptureIntentAndNotSetByDpc);
9097     }
9098 
updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc)9099     private int updateFlagsForResolve(int flags, int userId, int callingUid,
9100             boolean wantInstantApps, boolean onlyExposedExplicitly,
9101             boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
9102         return mComputer.updateFlagsForResolve(flags, userId, callingUid,
9103                 wantInstantApps, onlyExposedExplicitly,
9104                 isImplicitImageCaptureIntentAndNotSetByDpc);
9105     }
9106 
9107     @Override
getTargetSdkVersion(String packageName)9108     public int getTargetSdkVersion(String packageName)  {
9109         synchronized (mLock) {
9110             final AndroidPackage pkg = mPackages.get(packageName);
9111             if (pkg == null) {
9112                 return -1;
9113             }
9114 
9115             final PackageSetting ps = getPackageSetting(pkg.getPackageName());
9116             if (shouldFilterApplicationLocked(ps, Binder.getCallingUid(),
9117                     UserHandle.getCallingUserId())) {
9118                 return -1;
9119             }
9120             return pkg.getTargetSdkVersion();
9121         }
9122     }
9123 
9124     @Override
getActivityInfo(ComponentName component, int flags, int userId)9125     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
9126         return mComputer.getActivityInfo(component, flags, userId);
9127     }
9128 
9129     /**
9130      * Important: The provided filterCallingUid is used exclusively to filter out activities
9131      * that can be seen based on user state. It's typically the original caller uid prior
9132      * to clearing. Because it can only be provided by trusted code, its value can be
9133      * trusted and will be used as-is; unlike userId which will be validated by this method.
9134      */
getActivityInfoInternal(ComponentName component, int flags, int filterCallingUid, int userId)9135     private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
9136             int filterCallingUid, int userId) {
9137         return mComputer.getActivityInfoInternal(component, flags,
9138                 filterCallingUid, userId);
9139     }
9140 
9141     @Override
activitySupportsIntent(ComponentName component, Intent intent, String resolvedType)9142     public boolean activitySupportsIntent(ComponentName component, Intent intent,
9143             String resolvedType) {
9144         synchronized (mLock) {
9145             if (component.equals(mResolveComponentName)) {
9146                 // The resolver supports EVERYTHING!
9147                 return true;
9148             }
9149             final int callingUid = Binder.getCallingUid();
9150             final int callingUserId = UserHandle.getUserId(callingUid);
9151             ParsedActivity a = mComponentResolver.getActivity(component);
9152             if (a == null) {
9153                 return false;
9154             }
9155             PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
9156             if (ps == null) {
9157                 return false;
9158             }
9159             if (shouldFilterApplicationLocked(
9160                     ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
9161                 return false;
9162             }
9163             for (int i=0; i< a.getIntents().size(); i++) {
9164                 if (a.getIntents().get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
9165                         intent.getData(), intent.getCategories(), TAG) >= 0) {
9166                     return true;
9167                 }
9168             }
9169             return false;
9170         }
9171     }
9172 
9173     @Override
getReceiverInfo(ComponentName component, int flags, int userId)9174     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
9175         if (!mUserManager.exists(userId)) return null;
9176         final int callingUid = Binder.getCallingUid();
9177         flags = updateFlagsForComponent(flags, userId);
9178         enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
9179                 false /* checkShell */, "get receiver info");
9180         synchronized (mLock) {
9181             ParsedActivity a = mComponentResolver.getReceiver(component);
9182             if (DEBUG_PACKAGE_INFO) Log.v(
9183                 TAG, "getReceiverInfo " + component + ": " + a);
9184 
9185             if (a == null) {
9186                 return null;
9187             }
9188 
9189             AndroidPackage pkg = mPackages.get(a.getPackageName());
9190             if (pkg == null) {
9191                 return null;
9192             }
9193 
9194             if (mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) {
9195                 PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
9196                 if (ps == null) return null;
9197                 if (shouldFilterApplicationLocked(
9198                         ps, callingUid, component, TYPE_RECEIVER, userId)) {
9199                     return null;
9200                 }
9201                 return PackageInfoUtils.generateActivityInfo(pkg,
9202                         a, flags, ps.readUserState(userId), userId, ps);
9203             }
9204         }
9205         return null;
9206     }
9207 
9208     @Override
getSharedLibraries(String packageName, int flags, int userId)9209     public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
9210             int flags, int userId) {
9211         if (!mUserManager.exists(userId)) return null;
9212         Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
9213         final int callingUid = Binder.getCallingUid();
9214         if (getInstantAppPackageName(callingUid) != null) {
9215             return null;
9216         }
9217 
9218         flags = updateFlagsForPackage(flags, userId);
9219 
9220         final boolean canSeeStaticLibraries =
9221                 mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
9222                         == PERMISSION_GRANTED
9223                 || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
9224                         == PERMISSION_GRANTED
9225                 || canRequestPackageInstallsInternal(packageName, callingUid, userId,
9226                         false  /* throwIfPermNotDeclared*/)
9227                 || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
9228                         == PERMISSION_GRANTED
9229                 || mContext.checkCallingOrSelfPermission(
9230                         Manifest.permission.ACCESS_SHARED_LIBRARIES) == PERMISSION_GRANTED;
9231 
9232         synchronized (mLock) {
9233             List<SharedLibraryInfo> result = null;
9234 
9235             final int libCount = mSharedLibraries.size();
9236             for (int i = 0; i < libCount; i++) {
9237                 WatchedLongSparseArray<SharedLibraryInfo> versionedLib =
9238                         mSharedLibraries.valueAt(i);
9239                 if (versionedLib == null) {
9240                     continue;
9241                 }
9242 
9243                 final int versionCount = versionedLib.size();
9244                 for (int j = 0; j < versionCount; j++) {
9245                     SharedLibraryInfo libInfo = versionedLib.valueAt(j);
9246                     if (!canSeeStaticLibraries && libInfo.isStatic()) {
9247                         break;
9248                     }
9249                     final long identity = Binder.clearCallingIdentity();
9250                     try {
9251                         PackageInfo packageInfo = getPackageInfoVersioned(
9252                                 libInfo.getDeclaringPackage(), flags
9253                                         | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
9254                         if (packageInfo == null) {
9255                             continue;
9256                         }
9257                     } finally {
9258                         Binder.restoreCallingIdentity(identity);
9259                     }
9260 
9261                     SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getPath(),
9262                             libInfo.getPackageName(), libInfo.getAllCodePaths(),
9263                             libInfo.getName(), libInfo.getLongVersion(),
9264                             libInfo.getType(), libInfo.getDeclaringPackage(),
9265                             getPackagesUsingSharedLibraryLPr(libInfo, flags, callingUid, userId),
9266                             (libInfo.getDependencies() == null
9267                                     ? null
9268                                     : new ArrayList<>(libInfo.getDependencies())),
9269                             libInfo.isNative());
9270 
9271                     if (result == null) {
9272                         result = new ArrayList<>();
9273                     }
9274                     result.add(resLibInfo);
9275                 }
9276             }
9277 
9278             return result != null ? new ParceledListSlice<>(result) : null;
9279         }
9280     }
9281 
9282     @Nullable
9283     @Override
getDeclaredSharedLibraries( @onNull String packageName, int flags, @NonNull int userId)9284     public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
9285             @NonNull String packageName, int flags, @NonNull int userId) {
9286         mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_SHARED_LIBRARIES,
9287                 "getDeclaredSharedLibraries");
9288         int callingUid = Binder.getCallingUid();
9289         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
9290                 false /* checkShell */, "getDeclaredSharedLibraries");
9291 
9292         Preconditions.checkNotNull(packageName, "packageName cannot be null");
9293         Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
9294         if (!mUserManager.exists(userId)) {
9295             return null;
9296         }
9297 
9298         if (getInstantAppPackageName(callingUid) != null) {
9299             return null;
9300         }
9301 
9302         synchronized (mLock) {
9303             List<SharedLibraryInfo> result = null;
9304 
9305             int libraryCount = mSharedLibraries.size();
9306             for (int i = 0; i < libraryCount; i++) {
9307                 WatchedLongSparseArray<SharedLibraryInfo> versionedLibrary =
9308                         mSharedLibraries.valueAt(i);
9309                 if (versionedLibrary == null) {
9310                     continue;
9311                 }
9312 
9313                 int versionCount = versionedLibrary.size();
9314                 for (int j = 0; j < versionCount; j++) {
9315                     SharedLibraryInfo libraryInfo = versionedLibrary.valueAt(j);
9316 
9317                     VersionedPackage declaringPackage = libraryInfo.getDeclaringPackage();
9318                     if (!Objects.equals(declaringPackage.getPackageName(), packageName)) {
9319                         continue;
9320                     }
9321 
9322                     final long identity = Binder.clearCallingIdentity();
9323                     try {
9324                         PackageInfo packageInfo = getPackageInfoVersioned(declaringPackage, flags
9325                                 | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
9326                         if (packageInfo == null) {
9327                             continue;
9328                         }
9329                     } finally {
9330                         Binder.restoreCallingIdentity(identity);
9331                     }
9332 
9333                     SharedLibraryInfo resultLibraryInfo = new SharedLibraryInfo(
9334                             libraryInfo.getPath(), libraryInfo.getPackageName(),
9335                             libraryInfo.getAllCodePaths(), libraryInfo.getName(),
9336                             libraryInfo.getLongVersion(), libraryInfo.getType(),
9337                             libraryInfo.getDeclaringPackage(),
9338                             getPackagesUsingSharedLibraryLPr(
9339                                     libraryInfo, flags, callingUid, userId),
9340                             libraryInfo.getDependencies() == null
9341                                     ? null : new ArrayList<>(libraryInfo.getDependencies()),
9342                             libraryInfo.isNative());
9343 
9344                     if (result == null) {
9345                         result = new ArrayList<>();
9346                     }
9347                     result.add(resultLibraryInfo);
9348                 }
9349             }
9350 
9351             return result != null ? new ParceledListSlice<>(result) : null;
9352         }
9353     }
9354 
9355     @GuardedBy("mLock")
getPackagesUsingSharedLibraryLPr( SharedLibraryInfo libInfo, int flags, int callingUid, int userId)9356     private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
9357             SharedLibraryInfo libInfo, int flags, int callingUid, int userId) {
9358         List<VersionedPackage> versionedPackages = null;
9359         final int packageCount = mSettings.getPackagesLocked().size();
9360         for (int i = 0; i < packageCount; i++) {
9361             PackageSetting ps = mSettings.getPackagesLocked().valueAt(i);
9362 
9363             if (ps == null) {
9364                 continue;
9365             }
9366 
9367             if (!ps.readUserState(userId).isAvailable(flags)) {
9368                 continue;
9369             }
9370 
9371             final String libName = libInfo.getName();
9372             if (libInfo.isStatic()) {
9373                 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
9374                 if (libIdx < 0) {
9375                     continue;
9376                 }
9377                 if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getLongVersion()) {
9378                     continue;
9379                 }
9380                 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
9381                     continue;
9382                 }
9383                 if (versionedPackages == null) {
9384                     versionedPackages = new ArrayList<>();
9385                 }
9386                 // If the dependent is a static shared lib, use the public package name
9387                 String dependentPackageName = ps.name;
9388                 if (ps.pkg != null && ps.pkg.isStaticSharedLibrary()) {
9389                     dependentPackageName = ps.pkg.getManifestPackageName();
9390                 }
9391                 versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
9392             } else if (ps.pkg != null) {
9393                 if (ArrayUtils.contains(ps.pkg.getUsesLibraries(), libName)
9394                         || ArrayUtils.contains(ps.pkg.getUsesOptionalLibraries(), libName)) {
9395                     if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
9396                         continue;
9397                     }
9398                     if (versionedPackages == null) {
9399                         versionedPackages = new ArrayList<>();
9400                     }
9401                     versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
9402                 }
9403             }
9404         }
9405 
9406         return versionedPackages;
9407     }
9408 
9409     @Override
getServiceInfo(ComponentName component, int flags, int userId)9410     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
9411         return mComputer.getServiceInfo(component, flags, userId);
9412     }
9413 
9414     @Override
getProviderInfo(ComponentName component, int flags, int userId)9415     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
9416         if (!mUserManager.exists(userId)) return null;
9417         final int callingUid = Binder.getCallingUid();
9418         flags = updateFlagsForComponent(flags, userId);
9419         enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
9420                 false /* checkShell */, "get provider info");
9421         synchronized (mLock) {
9422             ParsedProvider p = mComponentResolver.getProvider(component);
9423             if (DEBUG_PACKAGE_INFO) Log.v(
9424                     TAG, "getProviderInfo " + component + ": " + p);
9425             if (p == null) {
9426                 return null;
9427             }
9428 
9429             AndroidPackage pkg = mPackages.get(p.getPackageName());
9430             if (pkg == null) {
9431                 return null;
9432             }
9433 
9434             if (mSettings.isEnabledAndMatchLPr(pkg, p, flags, userId)) {
9435                 PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
9436                 if (ps == null) return null;
9437                 if (shouldFilterApplicationLocked(
9438                         ps, callingUid, component, TYPE_PROVIDER, userId)) {
9439                     return null;
9440                 }
9441                 PackageUserState state = ps.readUserState(userId);
9442                 final ApplicationInfo appInfo = PackageInfoUtils.generateApplicationInfo(
9443                         pkg, flags, state, userId, ps);
9444                 if (appInfo == null) {
9445                     return null;
9446                 }
9447                 return PackageInfoUtils.generateProviderInfo(
9448                         pkg, p, flags, state, appInfo, userId, ps);
9449             }
9450         }
9451         return null;
9452     }
9453 
9454     @Override
getModuleInfo(String packageName, @ModuleInfoFlags int flags)9455     public ModuleInfo getModuleInfo(String packageName, @ModuleInfoFlags int flags) {
9456         return mModuleInfoProvider.getModuleInfo(packageName, flags);
9457     }
9458 
9459     @Override
getInstalledModules(int flags)9460     public List<ModuleInfo> getInstalledModules(int flags) {
9461         return mModuleInfoProvider.getInstalledModules(flags);
9462     }
9463 
9464     @Override
getSystemSharedLibraryNames()9465     public String[] getSystemSharedLibraryNames() {
9466         // allow instant applications
9467         synchronized (mLock) {
9468             Set<String> libs = null;
9469             final int libCount = mSharedLibraries.size();
9470             for (int i = 0; i < libCount; i++) {
9471                 WatchedLongSparseArray<SharedLibraryInfo> versionedLib =
9472                         mSharedLibraries.valueAt(i);
9473                 if (versionedLib == null) {
9474                     continue;
9475                 }
9476                 final int versionCount = versionedLib.size();
9477                 for (int j = 0; j < versionCount; j++) {
9478                     SharedLibraryInfo libraryInfo = versionedLib.valueAt(j);
9479                     if (!libraryInfo.isStatic()) {
9480                         if (libs == null) {
9481                             libs = new ArraySet<>();
9482                         }
9483                         libs.add(libraryInfo.getName());
9484                         break;
9485                     }
9486                     PackageSetting ps = mSettings.getPackageLPr(libraryInfo.getPackageName());
9487                     if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
9488                             UserHandle.getUserId(Binder.getCallingUid()),
9489                             PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
9490                         if (libs == null) {
9491                             libs = new ArraySet<>();
9492                         }
9493                         libs.add(libraryInfo.getName());
9494                         break;
9495                     }
9496                 }
9497             }
9498 
9499             if (libs != null) {
9500                 String[] libsArray = new String[libs.size()];
9501                 libs.toArray(libsArray);
9502                 return libsArray;
9503             }
9504 
9505             return null;
9506         }
9507     }
9508 
9509     @Override
getServicesSystemSharedLibraryPackageName()9510     public @NonNull String getServicesSystemSharedLibraryPackageName() {
9511         // allow instant applications
9512         synchronized (mLock) {
9513             return mServicesExtensionPackageName;
9514         }
9515     }
9516 
9517     @Override
getSharedSystemSharedLibraryPackageName()9518     public @NonNull String getSharedSystemSharedLibraryPackageName() {
9519         // allow instant applications
9520         synchronized (mLock) {
9521             return mSharedSystemSharedLibraryPackageName;
9522         }
9523     }
9524 
9525     @GuardedBy("mLock")
updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList)9526     private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
9527         for (int i = userList.length - 1; i >= 0; --i) {
9528             final int userId = userList[i];
9529             SparseArray<String> changedPackages = mChangedPackages.get(userId);
9530             if (changedPackages == null) {
9531                 changedPackages = new SparseArray<>();
9532                 mChangedPackages.put(userId, changedPackages);
9533             }
9534             Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
9535             if (sequenceNumbers == null) {
9536                 sequenceNumbers = new HashMap<>();
9537                 mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
9538             }
9539             final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
9540             if (sequenceNumber != null) {
9541                 changedPackages.remove(sequenceNumber);
9542             }
9543             changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
9544             sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
9545         }
9546         mChangedPackagesSequenceNumber++;
9547     }
9548 
9549     @Override
getChangedPackages(int sequenceNumber, int userId)9550     public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
9551         final int callingUid = Binder.getCallingUid();
9552         if (getInstantAppPackageName(callingUid) != null) {
9553             return null;
9554         }
9555         if (!mUserManager.exists(userId)) {
9556             return null;
9557         }
9558         enforceCrossUserPermission(callingUid, userId, false, false, "getChangedPackages");
9559         synchronized (mLock) {
9560             if (sequenceNumber >= mChangedPackagesSequenceNumber) {
9561                 return null;
9562             }
9563             final SparseArray<String> changedPackages = mChangedPackages.get(userId);
9564             if (changedPackages == null) {
9565                 return null;
9566             }
9567             final List<String> packageNames =
9568                     new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
9569             for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
9570                 final String packageName = changedPackages.get(i);
9571                 if (packageName != null) {
9572                     // Filter out the changes if the calling package should not be able to see it.
9573                     final PackageSetting ps = mSettings.getPackageLPr(packageName);
9574                     if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
9575                         continue;
9576                     }
9577                     packageNames.add(packageName);
9578                 }
9579             }
9580             return packageNames.isEmpty()
9581                     ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
9582         }
9583     }
9584 
9585     @Override
getSystemAvailableFeatures()9586     public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
9587         // allow instant applications
9588         ArrayList<FeatureInfo> res;
9589         synchronized (mAvailableFeatures) {
9590             res = new ArrayList<>(mAvailableFeatures.size() + 1);
9591             res.addAll(mAvailableFeatures.values());
9592         }
9593         final FeatureInfo fi = new FeatureInfo();
9594         fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
9595                 FeatureInfo.GL_ES_VERSION_UNDEFINED);
9596         res.add(fi);
9597 
9598         return new ParceledListSlice<>(res);
9599     }
9600 
9601     @Override
hasSystemFeature(String name, int version)9602     public boolean hasSystemFeature(String name, int version) {
9603         // allow instant applications
9604         synchronized (mAvailableFeatures) {
9605             final FeatureInfo feat = mAvailableFeatures.get(name);
9606             if (feat == null) {
9607                 return false;
9608             } else {
9609                 return feat.version >= version;
9610             }
9611         }
9612     }
9613 
9614     // NOTE: Can't remove due to unsupported app usage
9615     @Override
checkPermission(String permName, String pkgName, int userId)9616     public int checkPermission(String permName, String pkgName, int userId) {
9617         return mPermissionManager.checkPermission(pkgName, permName, userId);
9618     }
9619 
9620     // NOTE: Can't remove without a major refactor. Keep around for now.
9621     @Override
checkUidPermission(String permName, int uid)9622     public int checkUidPermission(String permName, int uid) {
9623         return mComputer.checkUidPermission(permName, uid);
9624     }
9625 
9626     @Override
getPermissionControllerPackageName()9627     public String getPermissionControllerPackageName() {
9628         synchronized (mLock) {
9629             if (mRequiredPermissionControllerPackage != null) {
9630                 final PackageSetting ps = getPackageSetting(mRequiredPermissionControllerPackage);
9631                 if (ps != null) {
9632                     final int callingUid = Binder.getCallingUid();
9633                     final int callingUserId = UserHandle.getUserId(callingUid);
9634                     if (!shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
9635                         return mRequiredPermissionControllerPackage;
9636                     }
9637                 }
9638             }
9639             throw new IllegalStateException("PermissionController is not found");
9640         }
9641     }
9642 
getPackageInstallerPackageName()9643     String getPackageInstallerPackageName() {
9644         synchronized (mLock) {
9645             return mRequiredInstallerPackage;
9646         }
9647     }
9648 
9649     // NOTE: Can't remove due to unsupported app usage
9650     @Override
addPermission(PermissionInfo info)9651     public boolean addPermission(PermissionInfo info) {
9652         // Because this is accessed via the package manager service AIDL,
9653         // go through the permission manager service AIDL
9654         return mContext.getSystemService(PermissionManager.class).addPermission(info, false);
9655     }
9656 
9657     // NOTE: Can't remove due to unsupported app usage
9658     @Override
addPermissionAsync(PermissionInfo info)9659     public boolean addPermissionAsync(PermissionInfo info) {
9660         // Because this is accessed via the package manager service AIDL,
9661         // go through the permission manager service AIDL
9662         return mContext.getSystemService(PermissionManager.class).addPermission(info, true);
9663     }
9664 
9665     // NOTE: Can't remove due to unsupported app usage
9666     @Override
removePermission(String permName)9667     public void removePermission(String permName) {
9668         // Because this is accessed via the package manager service AIDL,
9669         // go through the permission manager service AIDL
9670         mContext.getSystemService(PermissionManager.class).removePermission(permName);
9671     }
9672 
9673     // NOTE: Can't remove due to unsupported app usage
9674     @Override
grantRuntimePermission(String packageName, String permName, final int userId)9675     public void grantRuntimePermission(String packageName, String permName, final int userId) {
9676         // Because this is accessed via the package manager service AIDL,
9677         // go through the permission manager service AIDL
9678         mContext.getSystemService(PermissionManager.class)
9679                 .grantRuntimePermission(packageName, permName, UserHandle.of(userId));
9680     }
9681 
9682     @Override
isProtectedBroadcast(String actionName)9683     public boolean isProtectedBroadcast(String actionName) {
9684         if (actionName != null) {
9685             // TODO: remove these terrible hacks
9686             if (actionName.startsWith("android.net.netmon.lingerExpired")
9687                     || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
9688                     || actionName.startsWith("com.android.internal.telephony.data-reconnect")
9689                     || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
9690                 return true;
9691             }
9692         }
9693          // allow instant applications
9694         synchronized (mProtectedBroadcasts) {
9695             return mProtectedBroadcasts.contains(actionName);
9696         }
9697     }
9698 
9699     @Override
checkSignatures(String pkg1, String pkg2)9700     public int checkSignatures(String pkg1, String pkg2) {
9701         synchronized (mLock) {
9702             final AndroidPackage p1 = mPackages.get(pkg1);
9703             final AndroidPackage p2 = mPackages.get(pkg2);
9704             final PackageSetting ps1 = p1 == null ? null : getPackageSetting(p1.getPackageName());
9705             final PackageSetting ps2 = p2 == null ? null : getPackageSetting(p2.getPackageName());
9706             if (p1 == null || ps1 == null || p2 == null || ps2 == null) {
9707                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
9708             }
9709             final int callingUid = Binder.getCallingUid();
9710             final int callingUserId = UserHandle.getUserId(callingUid);
9711             if (shouldFilterApplicationLocked(ps1, callingUid, callingUserId)
9712                     || shouldFilterApplicationLocked(ps2, callingUid, callingUserId)) {
9713                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
9714             }
9715             return checkSignaturesInternal(p1.getSigningDetails(), p2.getSigningDetails());
9716         }
9717     }
9718 
9719     @Override
checkUidSignatures(int uid1, int uid2)9720     public int checkUidSignatures(int uid1, int uid2) {
9721         final int callingUid = Binder.getCallingUid();
9722         final int callingUserId = UserHandle.getUserId(callingUid);
9723         // Map to base uids.
9724         final int appId1 = UserHandle.getAppId(uid1);
9725         final int appId2 = UserHandle.getAppId(uid2);
9726         // reader
9727         synchronized (mLock) {
9728             SigningDetails p1SigningDetails;
9729             SigningDetails p2SigningDetails;
9730             Object obj = mSettings.getSettingLPr(appId1);
9731             if (obj != null) {
9732                 if (obj instanceof SharedUserSetting) {
9733                     final SharedUserSetting sus = (SharedUserSetting) obj;
9734                     if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
9735                         return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
9736                     }
9737                     p1SigningDetails = sus.signatures.mSigningDetails;
9738                 } else if (obj instanceof PackageSetting) {
9739                     final PackageSetting ps = (PackageSetting) obj;
9740                     if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
9741                         return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
9742                     }
9743                     p1SigningDetails = ps.signatures.mSigningDetails;
9744                 } else {
9745                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
9746                 }
9747             } else {
9748                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
9749             }
9750             obj = mSettings.getSettingLPr(appId2);
9751             if (obj != null) {
9752                 if (obj instanceof SharedUserSetting) {
9753                     final SharedUserSetting sus = (SharedUserSetting) obj;
9754                     if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
9755                         return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
9756                     }
9757                     p2SigningDetails = sus.signatures.mSigningDetails;
9758                 } else if (obj instanceof PackageSetting) {
9759                     final PackageSetting ps = (PackageSetting) obj;
9760                     if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
9761                         return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
9762                     }
9763                     p2SigningDetails = ps.signatures.mSigningDetails;
9764                 } else {
9765                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
9766                 }
9767             } else {
9768                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
9769             }
9770             return checkSignaturesInternal(p1SigningDetails, p2SigningDetails);
9771         }
9772     }
9773 
checkSignaturesInternal(SigningDetails p1SigningDetails, SigningDetails p2SigningDetails)9774     private int checkSignaturesInternal(SigningDetails p1SigningDetails,
9775             SigningDetails p2SigningDetails) {
9776         if (p1SigningDetails == null) {
9777             return p2SigningDetails == null
9778                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
9779                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
9780         }
9781         if (p2SigningDetails == null) {
9782             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
9783         }
9784         int result = compareSignatures(p1SigningDetails.signatures, p2SigningDetails.signatures);
9785         if (result == PackageManager.SIGNATURE_MATCH) {
9786             return result;
9787         }
9788         // To support backwards compatibility with clients of this API expecting pre-key
9789         // rotation results if either of the packages has a signing lineage the oldest signer
9790         // in the lineage is used for signature verification.
9791         if (p1SigningDetails.hasPastSigningCertificates()
9792                 || p2SigningDetails.hasPastSigningCertificates()) {
9793             Signature[] p1Signatures = p1SigningDetails.hasPastSigningCertificates()
9794                     ? new Signature[]{p1SigningDetails.pastSigningCertificates[0]}
9795                     : p1SigningDetails.signatures;
9796             Signature[] p2Signatures = p2SigningDetails.hasPastSigningCertificates()
9797                     ? new Signature[]{p2SigningDetails.pastSigningCertificates[0]}
9798                     : p2SigningDetails.signatures;
9799             result = compareSignatures(p1Signatures, p2Signatures);
9800         }
9801         return result;
9802     }
9803 
9804     @Override
hasSigningCertificate( String packageName, byte[] certificate, @PackageManager.CertificateInputType int type)9805     public boolean hasSigningCertificate(
9806             String packageName, byte[] certificate, @PackageManager.CertificateInputType int type) {
9807 
9808         synchronized (mLock) {
9809             final AndroidPackage p = mPackages.get(packageName);
9810             if (p == null) {
9811                 return false;
9812             }
9813             final PackageSetting ps = getPackageSetting(p.getPackageName());
9814             if (ps == null) {
9815                 return false;
9816             }
9817             final int callingUid = Binder.getCallingUid();
9818             final int callingUserId = UserHandle.getUserId(callingUid);
9819             if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
9820                 return false;
9821             }
9822             switch (type) {
9823                 case CERT_INPUT_RAW_X509:
9824                     return p.getSigningDetails().hasCertificate(certificate);
9825                 case CERT_INPUT_SHA256:
9826                     return p.getSigningDetails().hasSha256Certificate(certificate);
9827                 default:
9828                     return false;
9829             }
9830         }
9831     }
9832 
9833     @Override
hasUidSigningCertificate( int uid, byte[] certificate, @PackageManager.CertificateInputType int type)9834     public boolean hasUidSigningCertificate(
9835             int uid, byte[] certificate, @PackageManager.CertificateInputType int type) {
9836         final int callingUid = Binder.getCallingUid();
9837         final int callingUserId = UserHandle.getUserId(callingUid);
9838         // Map to base uids.
9839         final int appId = UserHandle.getAppId(uid);
9840         // reader
9841         synchronized (mLock) {
9842             final PackageParser.SigningDetails signingDetails;
9843             final Object obj = mSettings.getSettingLPr(appId);
9844             if (obj != null) {
9845                 if (obj instanceof SharedUserSetting) {
9846                     final SharedUserSetting sus = (SharedUserSetting) obj;
9847                     if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
9848                         return false;
9849                     }
9850                     signingDetails = sus.signatures.mSigningDetails;
9851                 } else if (obj instanceof PackageSetting) {
9852                     final PackageSetting ps = (PackageSetting) obj;
9853                     if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
9854                         return false;
9855                     }
9856                     signingDetails = ps.signatures.mSigningDetails;
9857                 } else {
9858                     return false;
9859                 }
9860             } else {
9861                 return false;
9862             }
9863             switch (type) {
9864                 case CERT_INPUT_RAW_X509:
9865                     return signingDetails.hasCertificate(certificate);
9866                 case CERT_INPUT_SHA256:
9867                     return signingDetails.hasSha256Certificate(certificate);
9868                 default:
9869                     return false;
9870             }
9871         }
9872     }
9873 
9874     /**
9875      * If the database version for this type of package (internal storage or
9876      * external storage) is less than the version where package signatures
9877      * were updated, return true.
9878      */
isCompatSignatureUpdateNeeded(AndroidPackage pkg)9879     private boolean isCompatSignatureUpdateNeeded(AndroidPackage pkg) {
9880         return isCompatSignatureUpdateNeeded(getSettingsVersionForPackage(pkg));
9881     }
9882 
isCompatSignatureUpdateNeeded(VersionInfo ver)9883     private static boolean isCompatSignatureUpdateNeeded(VersionInfo ver) {
9884         return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
9885     }
9886 
isRecoverSignatureUpdateNeeded(AndroidPackage pkg)9887     private boolean isRecoverSignatureUpdateNeeded(AndroidPackage pkg) {
9888         return isRecoverSignatureUpdateNeeded(getSettingsVersionForPackage(pkg));
9889     }
9890 
isRecoverSignatureUpdateNeeded(VersionInfo ver)9891     private static boolean isRecoverSignatureUpdateNeeded(VersionInfo ver) {
9892         return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
9893     }
9894 
9895     @Override
getAllPackages()9896     public List<String> getAllPackages() {
9897         // Allow iorapd to call this method.
9898         if (Binder.getCallingUid() != Process.IORAPD_UID) {
9899             enforceSystemOrRootOrShell("getAllPackages is limited to privileged callers");
9900         }
9901         final int callingUid = Binder.getCallingUid();
9902         final int callingUserId = UserHandle.getUserId(callingUid);
9903         synchronized (mLock) {
9904             if (canViewInstantApps(callingUid, callingUserId)) {
9905                 return new ArrayList<>(mPackages.keySet());
9906             }
9907             final String instantAppPkgName = getInstantAppPackageName(callingUid);
9908             final List<String> result = new ArrayList<>();
9909             if (instantAppPkgName != null) {
9910                 // caller is an instant application; filter unexposed applications
9911                 for (AndroidPackage pkg : mPackages.values()) {
9912                     if (!pkg.isVisibleToInstantApps()) {
9913                         continue;
9914                     }
9915                     result.add(pkg.getPackageName());
9916                 }
9917             } else {
9918                 // caller is a normal application; filter instant applications
9919                 for (AndroidPackage pkg : mPackages.values()) {
9920                     final PackageSetting ps = getPackageSetting(pkg.getPackageName());
9921                     if (ps != null
9922                             && ps.getInstantApp(callingUserId)
9923                             && !mInstantAppRegistry.isInstantAccessGranted(
9924                                     callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
9925                         continue;
9926                     }
9927                     result.add(pkg.getPackageName());
9928                 }
9929             }
9930             return result;
9931         }
9932     }
9933 
9934     /**
9935      * <em>IMPORTANT:</em> Not all packages returned by this method may be known
9936      * to the system. There are two conditions in which this may occur:
9937      * <ol>
9938      *   <li>The package is on adoptable storage and the device has been removed</li>
9939      *   <li>The package is being removed and the internal structures are partially updated</li>
9940      * </ol>
9941      * The second is an artifact of the current data structures and should be fixed. See
9942      * b/111075456 for one such instance.
9943      * This binder API is cached.  If the algorithm in this method changes,
9944      * or if the underlying objecs (as returned by getSettingLPr()) change
9945      * then the logic that invalidates the cache must be revisited.  See
9946      * calls to invalidateGetPackagesForUidCache() to locate the points at
9947      * which the cache is invalidated.
9948      */
9949     @Override
getPackagesForUid(int uid)9950     public String[] getPackagesForUid(int uid) {
9951         final int callingUid = Binder.getCallingUid();
9952         final int userId = UserHandle.getUserId(uid);
9953         enforceCrossUserOrProfilePermission(callingUid, userId,
9954                 /* requireFullPermission */ false,
9955                 /* checkShell */ false, "getPackagesForUid");
9956         return mComputer.getPackagesForUid(uid);
9957     }
9958 
9959     @Override
getNameForUid(int uid)9960     public String getNameForUid(int uid) {
9961         final int callingUid = Binder.getCallingUid();
9962         if (getInstantAppPackageName(callingUid) != null) {
9963             return null;
9964         }
9965         final int callingUserId = UserHandle.getUserId(callingUid);
9966         final int appId = UserHandle.getAppId(uid);
9967         synchronized (mLock) {
9968             final Object obj = mSettings.getSettingLPr(appId);
9969             if (obj instanceof SharedUserSetting) {
9970                 final SharedUserSetting sus = (SharedUserSetting) obj;
9971                 if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
9972                     return null;
9973                 }
9974                 return sus.name + ":" + sus.userId;
9975             } else if (obj instanceof PackageSetting) {
9976                 final PackageSetting ps = (PackageSetting) obj;
9977                 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
9978                     return null;
9979                 }
9980                 return ps.name;
9981             }
9982             return null;
9983         }
9984     }
9985 
9986     @Override
getNamesForUids(int[] uids)9987     public String[] getNamesForUids(int[] uids) {
9988         if (uids == null || uids.length == 0) {
9989             return null;
9990         }
9991         final int callingUid = Binder.getCallingUid();
9992         if (getInstantAppPackageName(callingUid) != null) {
9993             return null;
9994         }
9995         final int callingUserId = UserHandle.getUserId(callingUid);
9996         final String[] names = new String[uids.length];
9997         synchronized (mLock) {
9998             for (int i = uids.length - 1; i >= 0; i--) {
9999                 final int appId = UserHandle.getAppId(uids[i]);
10000                 final Object obj = mSettings.getSettingLPr(appId);
10001                 if (obj instanceof SharedUserSetting) {
10002                     final SharedUserSetting sus = (SharedUserSetting) obj;
10003                     if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
10004                         names[i] = null;
10005                     } else {
10006                         names[i] = "shared:" + sus.name;
10007                     }
10008                 } else if (obj instanceof PackageSetting) {
10009                     final PackageSetting ps = (PackageSetting) obj;
10010                     if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
10011                         names[i] = null;
10012                     } else {
10013                         names[i] = ps.name;
10014                     }
10015                 } else {
10016                     names[i] = null;
10017                 }
10018             }
10019         }
10020         return names;
10021     }
10022 
10023     @Override
getUidForSharedUser(String sharedUserName)10024     public int getUidForSharedUser(String sharedUserName) {
10025         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10026             return -1;
10027         }
10028         if (sharedUserName == null) {
10029             return -1;
10030         }
10031         // reader
10032         synchronized (mLock) {
10033             SharedUserSetting suid;
10034             try {
10035                 suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
10036                 if (suid != null) {
10037                     return suid.userId;
10038                 }
10039             } catch (PackageManagerException ignore) {
10040                 // can't happen, but, still need to catch it
10041             }
10042             return -1;
10043         }
10044     }
10045 
10046     @Override
getFlagsForUid(int uid)10047     public int getFlagsForUid(int uid) {
10048         final int callingUid = Binder.getCallingUid();
10049         if (getInstantAppPackageName(callingUid) != null) {
10050             return 0;
10051         }
10052         final int callingUserId = UserHandle.getUserId(callingUid);
10053         final int appId = UserHandle.getAppId(uid);
10054         synchronized (mLock) {
10055             final Object obj = mSettings.getSettingLPr(appId);
10056             if (obj instanceof SharedUserSetting) {
10057                 final SharedUserSetting sus = (SharedUserSetting) obj;
10058                 if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
10059                     return 0;
10060                 }
10061                 return sus.pkgFlags;
10062             } else if (obj instanceof PackageSetting) {
10063                 final PackageSetting ps = (PackageSetting) obj;
10064                 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
10065                     return 0;
10066                 }
10067                 return ps.pkgFlags;
10068             }
10069         }
10070         return 0;
10071     }
10072 
10073     @Override
getPrivateFlagsForUid(int uid)10074     public int getPrivateFlagsForUid(int uid) {
10075         final int callingUid = Binder.getCallingUid();
10076         if (getInstantAppPackageName(callingUid) != null) {
10077             return 0;
10078         }
10079         final int callingUserId = UserHandle.getUserId(callingUid);
10080         final int appId = UserHandle.getAppId(uid);
10081         synchronized (mLock) {
10082             final Object obj = mSettings.getSettingLPr(appId);
10083             if (obj instanceof SharedUserSetting) {
10084                 final SharedUserSetting sus = (SharedUserSetting) obj;
10085                 if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
10086                     return 0;
10087                 }
10088                 return sus.pkgPrivateFlags;
10089             } else if (obj instanceof PackageSetting) {
10090                 final PackageSetting ps = (PackageSetting) obj;
10091                 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
10092                     return 0;
10093                 }
10094                 return ps.pkgPrivateFlags;
10095             }
10096         }
10097         return 0;
10098     }
10099 
10100     @Override
isUidPrivileged(int uid)10101     public boolean isUidPrivileged(int uid) {
10102         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10103             return false;
10104         }
10105         final int appId = UserHandle.getAppId(uid);
10106         // reader
10107         synchronized (mLock) {
10108             final Object obj = mSettings.getSettingLPr(appId);
10109             if (obj instanceof SharedUserSetting) {
10110                 final SharedUserSetting sus = (SharedUserSetting) obj;
10111                 final int numPackages = sus.packages.size();
10112                 for (int index = 0; index < numPackages; index++) {
10113                     final PackageSetting ps = sus.packages.valueAt(index);
10114                     if (ps.isPrivileged()) {
10115                         return true;
10116                     }
10117                 }
10118             } else if (obj instanceof PackageSetting) {
10119                 final PackageSetting ps = (PackageSetting) obj;
10120                 return ps.isPrivileged();
10121             }
10122         }
10123         return false;
10124     }
10125 
10126     // NOTE: Can't remove due to unsupported app usage
10127     @NonNull
10128     @Override
getAppOpPermissionPackages(String permissionName)10129     public String[] getAppOpPermissionPackages(String permissionName) {
10130         if (permissionName == null) {
10131             return EmptyArray.STRING;
10132         }
10133         if (getInstantAppPackageName(getCallingUid()) != null) {
10134             return EmptyArray.STRING;
10135         }
10136         return mPermissionManager.getAppOpPermissionPackages(permissionName);
10137     }
10138 
10139     @Override
resolveIntent(Intent intent, String resolvedType, int flags, int userId)10140     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
10141             int flags, int userId) {
10142         return resolveIntentInternal(intent, resolvedType, flags, 0 /*privateResolveFlags*/,
10143                 userId, false, Binder.getCallingUid());
10144     }
10145 
10146     /**
10147      * Normally instant apps can only be resolved when they're visible to the caller.
10148      * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
10149      * since we need to allow the system to start any installed application.
10150      */
resolveIntentInternal(Intent intent, String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags, int userId, boolean resolveForStart, int filterCallingUid)10151     private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType, int flags,
10152             @PrivateResolveFlags int privateResolveFlags, int userId, boolean resolveForStart,
10153             int filterCallingUid) {
10154         try {
10155             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
10156 
10157             if (!mUserManager.exists(userId)) return null;
10158             final int callingUid = Binder.getCallingUid();
10159             flags = updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart,
10160                     isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
10161                             flags));
10162             enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
10163                     false /*checkShell*/, "resolve intent");
10164 
10165             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
10166             final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
10167                     flags, privateResolveFlags, filterCallingUid, userId, resolveForStart,
10168                     true /*allowDynamicSplits*/);
10169             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10170 
10171             final boolean queryMayBeFiltered =
10172                     UserHandle.getAppId(filterCallingUid) >= Process.FIRST_APPLICATION_UID
10173                             && !resolveForStart;
10174 
10175             final ResolveInfo bestChoice =
10176                     chooseBestActivity(
10177                             intent, resolvedType, flags, privateResolveFlags, query, userId,
10178                             queryMayBeFiltered);
10179             final boolean nonBrowserOnly =
10180                     (privateResolveFlags & PackageManagerInternal.RESOLVE_NON_BROWSER_ONLY) != 0;
10181             if (nonBrowserOnly && bestChoice != null && bestChoice.handleAllWebDataURI) {
10182                 return null;
10183             }
10184             return bestChoice;
10185         } finally {
10186             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10187         }
10188     }
10189 
10190     @Override
findPersistentPreferredActivity(Intent intent, int userId)10191     public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
10192         if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
10193             throw new SecurityException(
10194                     "findPersistentPreferredActivity can only be run by the system");
10195         }
10196         if (!mUserManager.exists(userId)) {
10197             return null;
10198         }
10199         final int callingUid = Binder.getCallingUid();
10200         intent = updateIntentForResolve(intent);
10201         final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
10202         final int flags = updateFlagsForResolve(
10203                 0, userId, callingUid, false /*includeInstantApps*/,
10204                 isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType, 0));
10205         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
10206                 userId);
10207         synchronized (mLock) {
10208             return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
10209                     userId);
10210         }
10211     }
10212 
10213     @Override
setLastChosenActivity(Intent intent, String resolvedType, int flags, IntentFilter filter, int match, ComponentName activity)10214     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
10215             IntentFilter filter, int match, ComponentName activity) {
10216         setLastChosenActivity(intent, resolvedType, flags,
10217                               new WatchedIntentFilter(filter), match, activity);
10218     }
10219 
10220     /**
10221      * Variant that takes a {@link WatchedIntentFilter}
10222      */
setLastChosenActivity(Intent intent, String resolvedType, int flags, WatchedIntentFilter filter, int match, ComponentName activity)10223     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
10224             WatchedIntentFilter filter, int match, ComponentName activity) {
10225         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10226             return;
10227         }
10228         final int userId = UserHandle.getCallingUserId();
10229         if (DEBUG_PREFERRED) {
10230             Log.v(TAG, "setLastChosenActivity intent=" + intent
10231                 + " resolvedType=" + resolvedType
10232                 + " flags=" + flags
10233                 + " filter=" + filter
10234                 + " match=" + match
10235                 + " activity=" + activity);
10236             filter.dump(new PrintStreamPrinter(System.out), "    ");
10237         }
10238         intent.setComponent(null);
10239         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
10240                 userId);
10241         // Find any earlier preferred or last chosen entries and nuke them
10242         findPreferredActivityNotLocked(
10243                 intent, resolvedType, flags, query, 0, false, true, false, userId);
10244         // Add the new activity as the last chosen for this filter
10245         addPreferredActivity(filter, match, null, activity, false, userId,
10246                 "Setting last chosen", false);
10247     }
10248 
10249     @Override
getLastChosenActivity(Intent intent, String resolvedType, int flags)10250     public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
10251         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10252             return null;
10253         }
10254         final int userId = UserHandle.getCallingUserId();
10255         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
10256         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
10257                 userId);
10258         return findPreferredActivityNotLocked(
10259                 intent, resolvedType, flags, query, 0, false, false, false, userId);
10260     }
10261 
requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj, Intent origIntent, String resolvedType, String callingPackage, @Nullable String callingFeatureId, boolean isRequesterInstantApp, Bundle verificationBundle, int userId)10262     private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
10263             Intent origIntent, String resolvedType, String callingPackage,
10264             @Nullable String callingFeatureId, boolean isRequesterInstantApp,
10265             Bundle verificationBundle, int userId) {
10266         final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
10267                 new InstantAppRequest(responseObj, origIntent, resolvedType,
10268                         callingPackage, callingFeatureId, isRequesterInstantApp, userId, verificationBundle,
10269                         false /*resolveForStart*/, responseObj.hostDigestPrefixSecure,
10270                         responseObj.token));
10271         mHandler.sendMessage(msg);
10272     }
10273 
chooseBestActivity(Intent intent, String resolvedType, int flags, int privateResolveFlags, List<ResolveInfo> query, int userId, boolean queryMayBeFiltered)10274     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
10275             int flags, int privateResolveFlags, List<ResolveInfo> query, int userId,
10276             boolean queryMayBeFiltered) {
10277         if (query != null) {
10278             final int N = query.size();
10279             if (N == 1) {
10280                 return query.get(0);
10281             } else if (N > 1) {
10282                 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
10283                 // If there is more than one activity with the same priority,
10284                 // then let the user decide between them.
10285                 ResolveInfo r0 = query.get(0);
10286                 ResolveInfo r1 = query.get(1);
10287                 if (DEBUG_INTENT_MATCHING || debug) {
10288                     Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
10289                             + r1.activityInfo.name + "=" + r1.priority);
10290                 }
10291                 // If the first activity has a higher priority, or a different
10292                 // default, then it is always desirable to pick it.
10293                 if (r0.priority != r1.priority
10294                         || r0.preferredOrder != r1.preferredOrder
10295                         || r0.isDefault != r1.isDefault) {
10296                     return query.get(0);
10297                 }
10298                 // If we have saved a preference for a preferred activity for
10299                 // this Intent, use that.
10300                 ResolveInfo ri = findPreferredActivityNotLocked(intent, resolvedType,
10301                         flags, query, r0.priority, true, false, debug, userId, queryMayBeFiltered);
10302                 if (ri != null) {
10303                     return ri;
10304                 }
10305                 int browserCount = 0;
10306                 for (int i = 0; i < N; i++) {
10307                     ri = query.get(i);
10308                     if (ri.handleAllWebDataURI) {
10309                         browserCount++;
10310                     }
10311                     // If we have an ephemeral app, use it
10312                     if (ri.activityInfo.applicationInfo.isInstantApp()) {
10313                         final String packageName = ri.activityInfo.packageName;
10314                         final PackageSetting ps = mSettings.getPackageLPr(packageName);
10315                         if (ps != null && hasAnyDomainApproval(mDomainVerificationManager, ps,
10316                                 intent, flags, userId)) {
10317                             return ri;
10318                         }
10319                     }
10320                 }
10321                 if ((privateResolveFlags
10322                         & PackageManagerInternal.RESOLVE_NON_RESOLVER_ONLY) != 0) {
10323                     return null;
10324                 }
10325                 ri = new ResolveInfo(mResolveInfo);
10326                 // if all resolve options are browsers, mark the resolver's info as if it were
10327                 // also a browser.
10328                 ri.handleAllWebDataURI = browserCount == N;
10329                 ri.activityInfo = new ActivityInfo(ri.activityInfo);
10330                 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
10331                 // If all of the options come from the same package, show the application's
10332                 // label and icon instead of the generic resolver's.
10333                 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
10334                 // and then throw away the ResolveInfo itself, meaning that the caller loses
10335                 // the resolvePackageName. Therefore the activityInfo.labelRes above provides
10336                 // a fallback for this case; we only set the target package's resources on
10337                 // the ResolveInfo, not the ActivityInfo.
10338                 final String intentPackage = intent.getPackage();
10339                 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
10340                     final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
10341                     ri.resolvePackageName = intentPackage;
10342                     if (userNeedsBadging(userId)) {
10343                         ri.noResourceId = true;
10344                     } else {
10345                         ri.icon = appi.icon;
10346                     }
10347                     ri.iconResourceId = appi.icon;
10348                     ri.labelRes = appi.labelRes;
10349                 }
10350                 ri.activityInfo.applicationInfo = new ApplicationInfo(
10351                         ri.activityInfo.applicationInfo);
10352                 if (userId != 0) {
10353                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
10354                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
10355                 }
10356                 // Make sure that the resolver is displayable in car mode
10357                 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
10358                 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
10359                 return ri;
10360             }
10361         }
10362         return null;
10363     }
10364 
10365     /**
10366      * Do NOT use for intent resolution filtering. That should be done with
10367      * {@link DomainVerificationManagerInternal#filterToApprovedApp(Intent, List, int, Function)}.
10368      *
10369      * @return if the package is approved at any non-zero level for the domain in the intent
10370      */
hasAnyDomainApproval( @onNull DomainVerificationManagerInternal manager, @NonNull PackageSetting pkgSetting, @NonNull Intent intent, @PackageManager.ResolveInfoFlags int resolveInfoFlags, @UserIdInt int userId)10371     private static boolean hasAnyDomainApproval(
10372             @NonNull DomainVerificationManagerInternal manager, @NonNull PackageSetting pkgSetting,
10373             @NonNull Intent intent, @PackageManager.ResolveInfoFlags int resolveInfoFlags,
10374             @UserIdInt int userId) {
10375         return manager.approvalLevelForDomain(pkgSetting, intent, resolveInfoFlags, userId)
10376                 > DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE;
10377     }
10378 
10379     /**
10380      * Return true if the given list is not empty and all of its contents have
10381      * an activityInfo with the given package name.
10382      */
allHavePackage(List<ResolveInfo> list, String packageName)10383     private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
10384         if (ArrayUtils.isEmpty(list)) {
10385             return false;
10386         }
10387         for (int i = 0, N = list.size(); i < N; i++) {
10388             final ResolveInfo ri = list.get(i);
10389             final ActivityInfo ai = ri != null ? ri.activityInfo : null;
10390             if (ai == null || !packageName.equals(ai.packageName)) {
10391                 return false;
10392             }
10393         }
10394         return true;
10395     }
10396 
10397     /**
10398      * From Android R, camera intents have to match system apps. The only exception to this is if
10399      * the DPC has set the camera persistent preferred activity. This case was introduced
10400      * because it is important that the DPC has the ability to set both system and non-system
10401      * camera persistent preferred activities.
10402      *
10403      * @return {@code true} if the intent is a camera intent and the persistent preferred
10404      * activity was not set by the DPC.
10405      */
10406     @GuardedBy("mLock")
isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId, String resolvedType, int flags)10407     private boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId,
10408             String resolvedType, int flags) {
10409         return mComputer.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId,
10410                 resolvedType, flags);
10411     }
10412 
10413     @GuardedBy("mLock")
findPersistentPreferredActivityLP(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean debug, int userId)10414     private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
10415             int flags, List<ResolveInfo> query, boolean debug, int userId) {
10416         final int N = query.size();
10417         PersistentPreferredIntentResolver ppir = mSettings.getPersistentPreferredActivities(userId);
10418         // Get the list of persistent preferred activities that handle the intent
10419         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
10420         List<PersistentPreferredActivity> pprefs = ppir != null
10421                 ? ppir.queryIntent(intent, resolvedType,
10422                         (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
10423                         userId)
10424                 : null;
10425         if (pprefs != null && pprefs.size() > 0) {
10426             final int M = pprefs.size();
10427             for (int i=0; i<M; i++) {
10428                 final PersistentPreferredActivity ppa = pprefs.get(i);
10429                 if (DEBUG_PREFERRED || debug) {
10430                     Slog.v(TAG, "Checking PersistentPreferredActivity ds="
10431                             + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
10432                             + "\n  component=" + ppa.mComponent);
10433                     ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
10434                 }
10435                 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
10436                         flags | MATCH_DISABLED_COMPONENTS, userId);
10437                 if (DEBUG_PREFERRED || debug) {
10438                     Slog.v(TAG, "Found persistent preferred activity:");
10439                     if (ai != null) {
10440                         ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
10441                     } else {
10442                         Slog.v(TAG, "  null");
10443                     }
10444                 }
10445                 if (ai == null) {
10446                     // This previously registered persistent preferred activity
10447                     // component is no longer known. Ignore it and do NOT remove it.
10448                     continue;
10449                 }
10450                 for (int j=0; j<N; j++) {
10451                     final ResolveInfo ri = query.get(j);
10452                     if (!ri.activityInfo.applicationInfo.packageName
10453                             .equals(ai.applicationInfo.packageName)) {
10454                         continue;
10455                     }
10456                     if (!ri.activityInfo.name.equals(ai.name)) {
10457                         continue;
10458                     }
10459                     //  Found a persistent preference that can handle the intent.
10460                     if (DEBUG_PREFERRED || debug) {
10461                         Slog.v(TAG, "Returning persistent preferred activity: " +
10462                                 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
10463                     }
10464                     return ri;
10465                 }
10466             }
10467         }
10468         return null;
10469     }
10470 
isHomeIntent(Intent intent)10471     private boolean isHomeIntent(Intent intent) {
10472         return ACTION_MAIN.equals(intent.getAction())
10473                 && intent.hasCategory(CATEGORY_HOME)
10474                 && intent.hasCategory(CATEGORY_DEFAULT);
10475     }
10476 
findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int priority, boolean always, boolean removeMatches, boolean debug, int userId)10477     ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
10478             List<ResolveInfo> query, int priority, boolean always,
10479             boolean removeMatches, boolean debug, int userId) {
10480         return findPreferredActivityNotLocked(
10481                 intent, resolvedType, flags, query, priority, always, removeMatches, debug, userId,
10482                 UserHandle.getAppId(Binder.getCallingUid()) >= Process.FIRST_APPLICATION_UID);
10483     }
10484 
10485     // TODO: handle preferred activities missing while user has amnesia
10486     /** <b>must not hold {@link #mLock}</b> */
findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int priority, boolean always, boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered)10487     ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
10488             List<ResolveInfo> query, int priority, boolean always,
10489             boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered) {
10490         if (Thread.holdsLock(mLock)) {
10491             Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
10492                     + " is holding mLock", new Throwable());
10493         }
10494         if (!mUserManager.exists(userId)) return null;
10495         final int callingUid = Binder.getCallingUid();
10496         // Do NOT hold the packages lock; this calls up into the settings provider which
10497         // could cause a deadlock.
10498         final boolean isDeviceProvisioned =
10499                 android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10500                         android.provider.Settings.Global.DEVICE_PROVISIONED, 0) == 1;
10501         flags = updateFlagsForResolve(
10502                 flags, userId, callingUid, false /*includeInstantApps*/,
10503                 isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
10504                         flags));
10505         intent = updateIntentForResolve(intent);
10506         // writer
10507         synchronized (mLock) {
10508             // Try to find a matching persistent preferred activity.
10509             ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
10510                     debug, userId);
10511 
10512             // If a persistent preferred activity matched, use it.
10513             if (pri != null) {
10514                 return pri;
10515             }
10516 
10517             PreferredIntentResolver pir = mSettings.getPreferredActivities(userId);
10518             // Get the list of preferred activities that handle the intent
10519             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
10520             List<PreferredActivity> prefs = pir != null
10521                     ? pir.queryIntent(intent, resolvedType,
10522                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
10523                             userId)
10524                     : null;
10525             if (prefs != null && prefs.size() > 0) {
10526                 boolean changed = false;
10527                 try {
10528                     // First figure out how good the original match set is.
10529                     // We will only allow preferred activities that came
10530                     // from the same match quality.
10531                     int match = 0;
10532 
10533                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
10534 
10535                     final int N = query.size();
10536                     for (int j=0; j<N; j++) {
10537                         final ResolveInfo ri = query.get(j);
10538                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
10539                                 + ": 0x" + Integer.toHexString(match));
10540                         if (ri.match > match) {
10541                             match = ri.match;
10542                         }
10543                     }
10544 
10545                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
10546                             + Integer.toHexString(match));
10547 
10548                     match &= IntentFilter.MATCH_CATEGORY_MASK;
10549                     final int M = prefs.size();
10550                     for (int i=0; i<M; i++) {
10551                         final PreferredActivity pa = prefs.get(i);
10552                         if (DEBUG_PREFERRED || debug) {
10553                             Slog.v(TAG, "Checking PreferredActivity ds="
10554                                     + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
10555                                     + "\n  component=" + pa.mPref.mComponent);
10556                             pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
10557                         }
10558                         if (pa.mPref.mMatch != match) {
10559                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
10560                                     + Integer.toHexString(pa.mPref.mMatch));
10561                             continue;
10562                         }
10563                         // If it's not an "always" type preferred activity and that's what we're
10564                         // looking for, skip it.
10565                         if (always && !pa.mPref.mAlways) {
10566                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
10567                             continue;
10568                         }
10569                         final ActivityInfo ai = getActivityInfo(
10570                                 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
10571                                         | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
10572                                 userId);
10573                         if (DEBUG_PREFERRED || debug) {
10574                             Slog.v(TAG, "Found preferred activity:");
10575                             if (ai != null) {
10576                                 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
10577                             } else {
10578                                 Slog.v(TAG, "  null");
10579                             }
10580                         }
10581                         final boolean excludeSetupWizardHomeActivity = isHomeIntent(intent)
10582                                 && !isDeviceProvisioned;
10583                         final boolean allowSetMutation = !excludeSetupWizardHomeActivity
10584                                 && !queryMayBeFiltered;
10585                         if (ai == null) {
10586                             // Do not remove launcher's preferred activity during SetupWizard
10587                             // due to it may not install yet
10588                             if (!allowSetMutation) {
10589                                 continue;
10590                             }
10591 
10592                             // This previously registered preferred activity
10593                             // component is no longer known.  Most likely an update
10594                             // to the app was installed and in the new version this
10595                             // component no longer exists.  Clean it up by removing
10596                             // it from the preferred activities list, and skip it.
10597                             Slog.w(TAG, "Removing dangling preferred activity: "
10598                                     + pa.mPref.mComponent);
10599                             pir.removeFilter(pa);
10600                             changed = true;
10601                             continue;
10602                         }
10603                         for (int j=0; j<N; j++) {
10604                             final ResolveInfo ri = query.get(j);
10605                             if (!ri.activityInfo.applicationInfo.packageName
10606                                     .equals(ai.applicationInfo.packageName)) {
10607                                 continue;
10608                             }
10609                             if (!ri.activityInfo.name.equals(ai.name)) {
10610                                 continue;
10611                             }
10612 
10613                             if (removeMatches && allowSetMutation) {
10614                                 pir.removeFilter(pa);
10615                                 changed = true;
10616                                 if (DEBUG_PREFERRED) {
10617                                     Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
10618                                 }
10619                                 break;
10620                             }
10621 
10622                             // Okay we found a previously set preferred or last chosen app.
10623                             // If the result set is different from when this
10624                             // was created, and is not a subset of the preferred set, we need to
10625                             // clear it and re-ask the user their preference, if we're looking for
10626                             // an "always" type entry.
10627 
10628                             if (always && !pa.mPref.sameSet(query, excludeSetupWizardHomeActivity)) {
10629                                 if (pa.mPref.isSuperset(query, excludeSetupWizardHomeActivity)) {
10630                                     if (allowSetMutation) {
10631                                         // some components of the set are no longer present in
10632                                         // the query, but the preferred activity can still be reused
10633                                         if (DEBUG_PREFERRED) {
10634                                             Slog.i(TAG, "Result set changed, but PreferredActivity"
10635                                                     + " is still valid as only non-preferred"
10636                                                     + " components were removed for " + intent
10637                                                     + " type " + resolvedType);
10638                                         }
10639                                         // remove obsolete components and re-add the up-to-date
10640                                         // filter
10641                                         PreferredActivity freshPa = new PreferredActivity(pa,
10642                                                 pa.mPref.mMatch,
10643                                                 pa.mPref.discardObsoleteComponents(query),
10644                                                 pa.mPref.mComponent,
10645                                                 pa.mPref.mAlways);
10646                                         pir.removeFilter(pa);
10647                                         pir.addFilter(freshPa);
10648                                         changed = true;
10649                                     } else {
10650                                         if (DEBUG_PREFERRED) {
10651                                             Slog.i(TAG, "Do not remove preferred activity");
10652                                         }
10653                                     }
10654                                 } else {
10655                                     if (allowSetMutation) {
10656                                         Slog.i(TAG,
10657                                                 "Result set changed, dropping preferred activity "
10658                                                         + "for " + intent + " type "
10659                                                         + resolvedType);
10660                                         if (DEBUG_PREFERRED) {
10661                                             Slog.v(TAG,
10662                                                     "Removing preferred activity since set changed "
10663                                                             + pa.mPref.mComponent);
10664                                         }
10665                                         pir.removeFilter(pa);
10666                                         // Re-add the filter as a "last chosen" entry (!always)
10667                                         PreferredActivity lastChosen = new PreferredActivity(
10668                                                 pa, pa.mPref.mMatch, null, pa.mPref.mComponent,
10669                                                 false);
10670                                         pir.addFilter(lastChosen);
10671                                         changed = true;
10672                                     }
10673                                     return null;
10674                                 }
10675                             }
10676 
10677                             // Yay! Either the set matched or we're looking for the last chosen
10678                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
10679                                     + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
10680                             return ri;
10681                         }
10682                     }
10683                 } finally {
10684                     if (changed) {
10685                         if (DEBUG_PREFERRED) {
10686                             Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
10687                         }
10688                         scheduleWritePackageRestrictionsLocked(userId);
10689                     }
10690                 }
10691             }
10692         }
10693         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
10694         return null;
10695     }
10696 
10697     /*
10698      * Returns if intent can be forwarded from the sourceUserId to the targetUserId
10699      */
10700     @Override
canForwardTo(Intent intent, String resolvedType, int sourceUserId, int targetUserId)10701     public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
10702             int targetUserId) {
10703         mContext.enforceCallingOrSelfPermission(
10704                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
10705         List<CrossProfileIntentFilter> matches =
10706                 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
10707         if (matches != null) {
10708             int size = matches.size();
10709             for (int i = 0; i < size; i++) {
10710                 if (matches.get(i).getTargetUserId() == targetUserId) return true;
10711             }
10712         }
10713         if (intent.hasWebURI()) {
10714             // cross-profile app linking works only towards the parent.
10715             final int callingUid = Binder.getCallingUid();
10716             final UserInfo parent = getProfileParent(sourceUserId);
10717             if (parent == null) {
10718                 return false;
10719             }
10720             synchronized (mLock) {
10721                 int flags = updateFlagsForResolve(0, parent.id, callingUid,
10722                         false /*includeInstantApps*/,
10723                         isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, parent.id,
10724                                 resolvedType, 0));
10725                 flags |= PackageManager.MATCH_DEFAULT_ONLY;
10726                 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
10727                         intent, resolvedType, flags, sourceUserId, parent.id);
10728                 return xpDomainInfo != null;
10729             }
10730         }
10731         return false;
10732     }
10733 
getProfileParent(int userId)10734     private UserInfo getProfileParent(int userId) {
10735         return mComputer.getProfileParent(userId);
10736     }
10737 
getMatchingCrossProfileIntentFilters(Intent intent, String resolvedType, int userId)10738     private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
10739             String resolvedType, int userId) {
10740         return mComputer.getMatchingCrossProfileIntentFilters(intent,
10741                 resolvedType, userId);
10742     }
10743 
10744     @Override
queryIntentActivities(Intent intent, String resolvedType, int flags, int userId)10745     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
10746             String resolvedType, int flags, int userId) {
10747         try {
10748             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
10749 
10750             return new ParceledListSlice<>(
10751                     queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
10752         } finally {
10753             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10754         }
10755     }
10756 
10757     /**
10758      * Returns the package name of the calling Uid if it's an instant app. If it isn't
10759      * instant, returns {@code null}.
10760      */
getInstantAppPackageName(int callingUid)10761     private String getInstantAppPackageName(int callingUid) {
10762         return mComputer.getInstantAppPackageName(callingUid);
10763     }
10764 
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, int userId)10765     private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
10766             String resolvedType, int flags, int userId) {
10767         return mComputer.queryIntentActivitiesInternal(intent,
10768                 resolvedType, flags, userId);
10769     }
10770 
10771     // Collect the results of queryIntentActivitiesInternalBody into a single class
10772     private static class QueryIntentActivitiesResult {
10773         public boolean sortResult = false;
10774         public boolean addInstant = false;
10775         public List<ResolveInfo> result = null;
10776         public List<ResolveInfo> answer = null;
10777 
QueryIntentActivitiesResult(List<ResolveInfo> l)10778         QueryIntentActivitiesResult(List<ResolveInfo> l) {
10779             answer = l;
10780         }
QueryIntentActivitiesResult(boolean s, boolean a, List<ResolveInfo> l)10781         QueryIntentActivitiesResult(boolean s, boolean a, List<ResolveInfo> l) {
10782             sortResult = s;
10783             addInstant = a;
10784             result = l;
10785         }
10786     }
10787 
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits)10788     private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
10789             String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags,
10790             int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits) {
10791         return mComputer.queryIntentActivitiesInternal(intent,
10792                 resolvedType, flags, privateResolveFlags,
10793                 filterCallingUid, userId, resolveForStart, allowDynamicSplits);
10794     }
10795 
queryIntentActivitiesInternalBody( Intent intent, String resolvedType, int flags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits, String pkgName, String instantAppPkgName)10796     private @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
10797             Intent intent, String resolvedType, int flags, int filterCallingUid, int userId,
10798             boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
10799             String instantAppPkgName) {
10800         return mComputer.queryIntentActivitiesInternalBody(
10801             intent, resolvedType, flags, filterCallingUid, userId,
10802             resolveForStart, allowDynamicSplits, pkgName,
10803             instantAppPkgName);
10804     }
10805 
10806     private static class CrossProfileDomainInfo {
10807         /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
10808         ResolveInfo resolveInfo;
10809         int highestApprovalLevel;
10810 
CrossProfileDomainInfo(ResolveInfo resolveInfo, int highestApprovalLevel)10811         CrossProfileDomainInfo(ResolveInfo resolveInfo, int highestApprovalLevel) {
10812             this.resolveInfo = resolveInfo;
10813             this.highestApprovalLevel = highestApprovalLevel;
10814         }
10815 
10816         @Override
toString()10817         public String toString() {
10818             return "CrossProfileDomainInfo{"
10819                     + "resolveInfo=" + resolveInfo
10820                     + ", highestApprovalLevel=" + highestApprovalLevel
10821                     + '}';
10822         }
10823     }
10824 
getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType, int flags, int sourceUserId, int parentUserId)10825     private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
10826             String resolvedType, int flags, int sourceUserId, int parentUserId) {
10827         return mComputer.getCrossProfileDomainPreferredLpr(intent,
10828                 resolvedType, flags, sourceUserId, parentUserId);
10829     }
10830 
10831     /**
10832      * Filters out ephemeral activities.
10833      * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
10834      * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
10835      *
10836      * @param resolveInfos The pre-filtered list of resolved activities
10837      * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
10838      *          is performed.
10839      * @param intent
10840      * @return A filtered list of resolved activities.
10841      */
applyPostResolutionFilter(@onNull List<ResolveInfo> resolveInfos, String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, boolean resolveForStart, int userId, Intent intent)10842     private List<ResolveInfo> applyPostResolutionFilter(@NonNull List<ResolveInfo> resolveInfos,
10843             String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
10844             boolean resolveForStart, int userId, Intent intent) {
10845         return mComputer.applyPostResolutionFilter(resolveInfos,
10846                 ephemeralPkgName, allowDynamicSplits, filterCallingUid,
10847                 resolveForStart, userId, intent);
10848     }
10849 
10850     @Override
queryIntentActivityOptions(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags, int userId)10851     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
10852             Intent[] specifics, String[] specificTypes, Intent intent,
10853             String resolvedType, int flags, int userId) {
10854         return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
10855                 specificTypes, intent, resolvedType, flags, userId));
10856     }
10857 
queryIntentActivityOptionsInternal(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags, int userId)10858     private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
10859             Intent[] specifics, String[] specificTypes, Intent intent,
10860             String resolvedType, int flags, int userId) {
10861         if (!mUserManager.exists(userId)) return Collections.emptyList();
10862         final int callingUid = Binder.getCallingUid();
10863         flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
10864                 isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
10865                         flags));
10866         enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
10867                 false /*checkShell*/, "query intent activity options");
10868         final String resultsAction = intent.getAction();
10869 
10870         final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
10871                 | PackageManager.GET_RESOLVED_FILTER, userId);
10872 
10873         if (DEBUG_INTENT_MATCHING) {
10874             Log.v(TAG, "Query " + intent + ": " + results);
10875         }
10876 
10877         int specificsPos = 0;
10878         int N;
10879 
10880         // todo: note that the algorithm used here is O(N^2).  This
10881         // isn't a problem in our current environment, but if we start running
10882         // into situations where we have more than 5 or 10 matches then this
10883         // should probably be changed to something smarter...
10884 
10885         // First we go through and resolve each of the specific items
10886         // that were supplied, taking care of removing any corresponding
10887         // duplicate items in the generic resolve list.
10888         if (specifics != null) {
10889             for (int i=0; i<specifics.length; i++) {
10890                 final Intent sintent = specifics[i];
10891                 if (sintent == null) {
10892                     continue;
10893                 }
10894 
10895                 if (DEBUG_INTENT_MATCHING) {
10896                     Log.v(TAG, "Specific #" + i + ": " + sintent);
10897                 }
10898 
10899                 String action = sintent.getAction();
10900                 if (resultsAction != null && resultsAction.equals(action)) {
10901                     // If this action was explicitly requested, then don't
10902                     // remove things that have it.
10903                     action = null;
10904                 }
10905 
10906                 ResolveInfo ri = null;
10907                 ActivityInfo ai = null;
10908 
10909                 ComponentName comp = sintent.getComponent();
10910                 if (comp == null) {
10911                     ri = resolveIntent(
10912                         sintent,
10913                         specificTypes != null ? specificTypes[i] : null,
10914                             flags, userId);
10915                     if (ri == null) {
10916                         continue;
10917                     }
10918                     if (ri == mResolveInfo) {
10919                         // ACK!  Must do something better with this.
10920                     }
10921                     ai = ri.activityInfo;
10922                     comp = new ComponentName(ai.applicationInfo.packageName,
10923                             ai.name);
10924                 } else {
10925                     ai = getActivityInfo(comp, flags, userId);
10926                     if (ai == null) {
10927                         continue;
10928                     }
10929                 }
10930 
10931                 // Look for any generic query activities that are duplicates
10932                 // of this specific one, and remove them from the results.
10933                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
10934                 N = results.size();
10935                 int j;
10936                 for (j=specificsPos; j<N; j++) {
10937                     ResolveInfo sri = results.get(j);
10938                     if ((sri.activityInfo.name.equals(comp.getClassName())
10939                             && sri.activityInfo.applicationInfo.packageName.equals(
10940                                     comp.getPackageName()))
10941                         || (action != null && sri.filter.matchAction(action))) {
10942                         results.remove(j);
10943                         if (DEBUG_INTENT_MATCHING) Log.v(
10944                             TAG, "Removing duplicate item from " + j
10945                             + " due to specific " + specificsPos);
10946                         if (ri == null) {
10947                             ri = sri;
10948                         }
10949                         j--;
10950                         N--;
10951                     }
10952                 }
10953 
10954                 // Add this specific item to its proper place.
10955                 if (ri == null) {
10956                     ri = new ResolveInfo();
10957                     ri.activityInfo = ai;
10958                 }
10959                 results.add(specificsPos, ri);
10960                 ri.specificIndex = i;
10961                 specificsPos++;
10962             }
10963         }
10964 
10965         // Now we go through the remaining generic results and remove any
10966         // duplicate actions that are found here.
10967         N = results.size();
10968         for (int i=specificsPos; i<N-1; i++) {
10969             final ResolveInfo rii = results.get(i);
10970             if (rii.filter == null) {
10971                 continue;
10972             }
10973 
10974             // Iterate over all of the actions of this result's intent
10975             // filter...  typically this should be just one.
10976             final Iterator<String> it = rii.filter.actionsIterator();
10977             if (it == null) {
10978                 continue;
10979             }
10980             while (it.hasNext()) {
10981                 final String action = it.next();
10982                 if (resultsAction != null && resultsAction.equals(action)) {
10983                     // If this action was explicitly requested, then don't
10984                     // remove things that have it.
10985                     continue;
10986                 }
10987                 for (int j=i+1; j<N; j++) {
10988                     final ResolveInfo rij = results.get(j);
10989                     if (rij.filter != null && rij.filter.hasAction(action)) {
10990                         results.remove(j);
10991                         if (DEBUG_INTENT_MATCHING) Log.v(
10992                             TAG, "Removing duplicate item from " + j
10993                             + " due to action " + action + " at " + i);
10994                         j--;
10995                         N--;
10996                     }
10997                 }
10998             }
10999 
11000             // If the caller didn't request filter information, drop it now
11001             // so we don't have to marshall/unmarshall it.
11002             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
11003                 rii.filter = null;
11004             }
11005         }
11006 
11007         // Filter out the caller activity if so requested.
11008         if (caller != null) {
11009             N = results.size();
11010             for (int i=0; i<N; i++) {
11011                 ActivityInfo ainfo = results.get(i).activityInfo;
11012                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
11013                         && caller.getClassName().equals(ainfo.name)) {
11014                     results.remove(i);
11015                     break;
11016                 }
11017             }
11018         }
11019 
11020         // If the caller didn't request filter information,
11021         // drop them now so we don't have to
11022         // marshall/unmarshall it.
11023         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
11024             N = results.size();
11025             for (int i=0; i<N; i++) {
11026                 results.get(i).filter = null;
11027             }
11028         }
11029 
11030         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
11031         return results;
11032     }
11033 
11034     @Override
queryIntentReceivers(Intent intent, String resolvedType, int flags, int userId)11035     public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
11036             String resolvedType, int flags, int userId) {
11037         return new ParceledListSlice<>(
11038                 queryIntentReceiversInternal(intent, resolvedType, flags, userId,
11039                         false /*allowDynamicSplits*/));
11040     }
11041 
queryIntentReceiversInternal(Intent intent, String resolvedType, int flags, int userId, boolean allowDynamicSplits)11042     private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
11043             String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
11044         if (!mUserManager.exists(userId)) return Collections.emptyList();
11045         final int callingUid = Binder.getCallingUid();
11046         enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
11047                 false /*checkShell*/, "query intent receivers");
11048         final String instantAppPkgName = getInstantAppPackageName(callingUid);
11049         flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
11050                 isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
11051                         flags));
11052         ComponentName comp = intent.getComponent();
11053         if (comp == null) {
11054             if (intent.getSelector() != null) {
11055                 intent = intent.getSelector();
11056                 comp = intent.getComponent();
11057             }
11058         }
11059         if (comp != null) {
11060             final List<ResolveInfo> list = new ArrayList<>(1);
11061             final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
11062             if (ai != null) {
11063                 // When specifying an explicit component, we prevent the activity from being
11064                 // used when either 1) the calling package is normal and the activity is within
11065                 // an instant application or 2) the calling package is ephemeral and the
11066                 // activity is not visible to instant applications.
11067                 final boolean matchInstantApp =
11068                         (flags & PackageManager.MATCH_INSTANT) != 0;
11069                 final boolean matchVisibleToInstantAppOnly =
11070                         (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
11071                 final boolean matchExplicitlyVisibleOnly =
11072                         (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
11073                 final boolean isCallerInstantApp =
11074                         instantAppPkgName != null;
11075                 final boolean isTargetSameInstantApp =
11076                         comp.getPackageName().equals(instantAppPkgName);
11077                 final boolean isTargetInstantApp =
11078                         (ai.applicationInfo.privateFlags
11079                                 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
11080                 final boolean isTargetVisibleToInstantApp =
11081                         (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
11082                 final boolean isTargetExplicitlyVisibleToInstantApp =
11083                         isTargetVisibleToInstantApp
11084                         && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
11085                 final boolean isTargetHiddenFromInstantApp =
11086                         !isTargetVisibleToInstantApp
11087                         || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
11088                 final boolean blockResolution =
11089                         !isTargetSameInstantApp
11090                         && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
11091                                 || (matchVisibleToInstantAppOnly && isCallerInstantApp
11092                                         && isTargetHiddenFromInstantApp));
11093                 if (!blockResolution) {
11094                     ResolveInfo ri = new ResolveInfo();
11095                     ri.activityInfo = ai;
11096                     list.add(ri);
11097                 }
11098             }
11099             return applyPostResolutionFilter(
11100                     list, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
11101                     intent);
11102         }
11103 
11104         // reader
11105         synchronized (mLock) {
11106             String pkgName = intent.getPackage();
11107             if (pkgName == null) {
11108                 final List<ResolveInfo> result =
11109                         mComponentResolver.queryReceivers(intent, resolvedType, flags, userId);
11110                 if (result == null) {
11111                     return Collections.emptyList();
11112                 }
11113                 return applyPostResolutionFilter(
11114                         result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
11115                         intent);
11116             }
11117             final AndroidPackage pkg = mPackages.get(pkgName);
11118             if (pkg != null) {
11119                 final List<ResolveInfo> result = mComponentResolver.queryReceivers(
11120                         intent, resolvedType, flags, pkg.getReceivers(), userId);
11121                 if (result == null) {
11122                     return Collections.emptyList();
11123                 }
11124                 return applyPostResolutionFilter(
11125                         result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
11126                         intent);
11127             }
11128             return Collections.emptyList();
11129         }
11130     }
11131 
11132     @Override
resolveService(Intent intent, String resolvedType, int flags, int userId)11133     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
11134         final int callingUid = Binder.getCallingUid();
11135         return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
11136     }
11137 
resolveServiceInternal(Intent intent, String resolvedType, int flags, int userId, int callingUid)11138     private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
11139             int userId, int callingUid) {
11140         if (!mUserManager.exists(userId)) return null;
11141         flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
11142                 false /* isImplicitImageCaptureIntentAndNotSetByDpc */);
11143         List<ResolveInfo> query = queryIntentServicesInternal(
11144                 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
11145         if (query != null) {
11146             if (query.size() >= 1) {
11147                 // If there is more than one service with the same priority,
11148                 // just arbitrarily pick the first one.
11149                 return query.get(0);
11150             }
11151         }
11152         return null;
11153     }
11154 
11155     @Override
queryIntentServices(Intent intent, String resolvedType, int flags, int userId)11156     public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
11157             String resolvedType, int flags, int userId) {
11158         final int callingUid = Binder.getCallingUid();
11159         return new ParceledListSlice<>(queryIntentServicesInternal(
11160                 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
11161     }
11162 
queryIntentServicesInternal(Intent intent, String resolvedType, int flags, int userId, int callingUid, boolean includeInstantApps)11163     private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
11164             String resolvedType, int flags, int userId, int callingUid,
11165             boolean includeInstantApps) {
11166         return mComputer.queryIntentServicesInternal(intent,
11167                 resolvedType, flags, userId, callingUid,
11168                 includeInstantApps);
11169     }
11170 
11171     @Override
queryIntentContentProviders(Intent intent, String resolvedType, int flags, int userId)11172     public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
11173             String resolvedType, int flags, int userId) {
11174         return new ParceledListSlice<>(
11175                 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
11176     }
11177 
queryIntentContentProvidersInternal( Intent intent, String resolvedType, int flags, int userId)11178     private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
11179             Intent intent, String resolvedType, int flags, int userId) {
11180         if (!mUserManager.exists(userId)) return Collections.emptyList();
11181         final int callingUid = Binder.getCallingUid();
11182         final String instantAppPkgName = getInstantAppPackageName(callingUid);
11183         flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
11184                 false /* isImplicitImageCaptureIntentAndNotSetByDpc */);
11185         ComponentName comp = intent.getComponent();
11186         if (comp == null) {
11187             if (intent.getSelector() != null) {
11188                 intent = intent.getSelector();
11189                 comp = intent.getComponent();
11190             }
11191         }
11192         if (comp != null) {
11193             final List<ResolveInfo> list = new ArrayList<>(1);
11194             final ProviderInfo pi = getProviderInfo(comp, flags, userId);
11195             if (pi != null) {
11196                 // When specifying an explicit component, we prevent the provider from being
11197                 // used when either 1) the provider is in an instant application and the
11198                 // caller is not the same instant application or 2) the calling package is an
11199                 // instant application and the provider is not visible to instant applications.
11200                 final boolean matchInstantApp =
11201                         (flags & PackageManager.MATCH_INSTANT) != 0;
11202                 final boolean matchVisibleToInstantAppOnly =
11203                         (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
11204                 final boolean isCallerInstantApp =
11205                         instantAppPkgName != null;
11206                 final boolean isTargetSameInstantApp =
11207                         comp.getPackageName().equals(instantAppPkgName);
11208                 final boolean isTargetInstantApp =
11209                         (pi.applicationInfo.privateFlags
11210                                 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
11211                 final boolean isTargetHiddenFromInstantApp =
11212                         (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
11213                 final boolean blockResolution =
11214                         !isTargetSameInstantApp
11215                         && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
11216                                 || (matchVisibleToInstantAppOnly && isCallerInstantApp
11217                                         && isTargetHiddenFromInstantApp));
11218                 final boolean blockNormalResolution = !isTargetInstantApp && !isCallerInstantApp
11219                         && shouldFilterApplicationLocked(
11220                         getPackageSettingInternal(pi.applicationInfo.packageName,
11221                                 Process.SYSTEM_UID), callingUid, userId);
11222                 if (!blockResolution && !blockNormalResolution) {
11223                     final ResolveInfo ri = new ResolveInfo();
11224                     ri.providerInfo = pi;
11225                     list.add(ri);
11226                 }
11227             }
11228             return list;
11229         }
11230 
11231         // reader
11232         synchronized (mLock) {
11233             String pkgName = intent.getPackage();
11234             if (pkgName == null) {
11235                 final List<ResolveInfo> resolveInfos = mComponentResolver.queryProviders(intent,
11236                         resolvedType, flags, userId);
11237                 if (resolveInfos == null) {
11238                     return Collections.emptyList();
11239                 }
11240                 return applyPostContentProviderResolutionFilter(
11241                         resolveInfos, instantAppPkgName, userId, callingUid);
11242             }
11243             final AndroidPackage pkg = mPackages.get(pkgName);
11244             if (pkg != null) {
11245                 final List<ResolveInfo> resolveInfos = mComponentResolver.queryProviders(intent,
11246                         resolvedType, flags,
11247                         pkg.getProviders(), userId);
11248                 if (resolveInfos == null) {
11249                     return Collections.emptyList();
11250                 }
11251                 return applyPostContentProviderResolutionFilter(
11252                         resolveInfos, instantAppPkgName, userId, callingUid);
11253             }
11254             return Collections.emptyList();
11255         }
11256     }
11257 
applyPostContentProviderResolutionFilter( List<ResolveInfo> resolveInfos, String instantAppPkgName, @UserIdInt int userId, int callingUid)11258     private List<ResolveInfo> applyPostContentProviderResolutionFilter(
11259             List<ResolveInfo> resolveInfos, String instantAppPkgName,
11260             @UserIdInt int userId, int callingUid) {
11261         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
11262             final ResolveInfo info = resolveInfos.get(i);
11263 
11264             if (instantAppPkgName == null) {
11265                 SettingBase callingSetting =
11266                         mSettings.getSettingLPr(UserHandle.getAppId(callingUid));
11267                 PackageSetting resolvedSetting =
11268                         getPackageSettingInternal(info.providerInfo.packageName, 0);
11269                 if (!mAppsFilter.shouldFilterApplication(
11270                         callingUid, callingSetting, resolvedSetting, userId)) {
11271                     continue;
11272                 }
11273             }
11274 
11275             final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
11276             // allow providers that are defined in the provided package
11277             if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
11278                 if (info.providerInfo.splitName != null
11279                         && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
11280                                 info.providerInfo.splitName)) {
11281                     if (mInstantAppInstallerActivity == null) {
11282                         if (DEBUG_INSTANT) {
11283                             Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
11284                         }
11285                         resolveInfos.remove(i);
11286                         continue;
11287                     }
11288                     // requested provider is defined in a split that hasn't been installed yet.
11289                     // add the installer to the resolve list
11290                     if (DEBUG_INSTANT) {
11291                         Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
11292                     }
11293                     final ResolveInfo installerInfo = new ResolveInfo(
11294                             mInstantAppInstallerInfo);
11295                     installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
11296                             null /*failureActivity*/,
11297                             info.providerInfo.packageName,
11298                             info.providerInfo.applicationInfo.longVersionCode,
11299                             info.providerInfo.splitName);
11300                     // add a non-generic filter
11301                     installerInfo.filter = new IntentFilter();
11302                     // load resources from the correct package
11303                     installerInfo.resolvePackageName = info.getComponentInfo().packageName;
11304                     resolveInfos.set(i, installerInfo);
11305                 }
11306                 continue;
11307             }
11308             // allow providers that have been explicitly exposed to instant applications
11309             if (!isEphemeralApp
11310                     && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
11311                 continue;
11312             }
11313             resolveInfos.remove(i);
11314         }
11315         return resolveInfos;
11316     }
11317 
11318     @Override
getInstalledPackages(int flags, int userId)11319     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
11320         return mComputer.getInstalledPackages(flags, userId);
11321     }
11322 
addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, String[] permissions, boolean[] tmp, int flags, int userId)11323     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
11324             String[] permissions, boolean[] tmp, int flags, int userId) {
11325         int numMatch = 0;
11326         for (int i=0; i<permissions.length; i++) {
11327             final String permission = permissions[i];
11328             if (checkPermission(permission, ps.name, userId) == PERMISSION_GRANTED) {
11329                 tmp[i] = true;
11330                 numMatch++;
11331             } else {
11332                 tmp[i] = false;
11333             }
11334         }
11335         if (numMatch == 0) {
11336             return;
11337         }
11338         final PackageInfo pi = generatePackageInfo(ps, flags, userId);
11339 
11340         // The above might return null in cases of uninstalled apps or install-state
11341         // skew across users/profiles.
11342         if (pi != null) {
11343             if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
11344                 if (numMatch == permissions.length) {
11345                     pi.requestedPermissions = permissions;
11346                 } else {
11347                     pi.requestedPermissions = new String[numMatch];
11348                     numMatch = 0;
11349                     for (int i=0; i<permissions.length; i++) {
11350                         if (tmp[i]) {
11351                             pi.requestedPermissions[numMatch] = permissions[i];
11352                             numMatch++;
11353                         }
11354                     }
11355                 }
11356             }
11357             list.add(pi);
11358         }
11359     }
11360 
11361     @Override
getPackagesHoldingPermissions( String[] permissions, int flags, int userId)11362     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
11363             String[] permissions, int flags, int userId) {
11364         if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
11365         flags = updateFlagsForPackage(flags, userId);
11366         enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
11367                 false /* checkShell */, "get packages holding permissions");
11368         final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
11369 
11370         // writer
11371         synchronized (mLock) {
11372             ArrayList<PackageInfo> list = new ArrayList<>();
11373             boolean[] tmpBools = new boolean[permissions.length];
11374             if (listUninstalled) {
11375                 for (PackageSetting ps : mSettings.getPackagesLocked().values()) {
11376                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
11377                             userId);
11378                 }
11379             } else {
11380                 for (AndroidPackage pkg : mPackages.values()) {
11381                     PackageSetting ps = getPackageSetting(pkg.getPackageName());
11382                     if (ps != null) {
11383                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
11384                                 userId);
11385                     }
11386                 }
11387             }
11388 
11389             return new ParceledListSlice<>(list);
11390         }
11391     }
11392 
11393     @Override
getInstalledApplications(int flags, int userId)11394     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
11395         final int callingUid = Binder.getCallingUid();
11396         return new ParceledListSlice<>(
11397                 getInstalledApplicationsListInternal(flags, userId, callingUid));
11398     }
11399 
getInstalledApplicationsListInternal(int flags, int userId, int callingUid)11400     private List<ApplicationInfo> getInstalledApplicationsListInternal(int flags, int userId,
11401             int callingUid) {
11402         if (getInstantAppPackageName(callingUid) != null) {
11403             return Collections.emptyList();
11404         }
11405         if (!mUserManager.exists(userId)) return Collections.emptyList();
11406         flags = updateFlagsForApplication(flags, userId);
11407         final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
11408 
11409         enforceCrossUserPermission(
11410             callingUid,
11411             userId,
11412             false /* requireFullPermission */,
11413             false /* checkShell */,
11414             "get installed application info");
11415 
11416         // writer
11417         synchronized (mLock) {
11418             ArrayList<ApplicationInfo> list;
11419             if (listUninstalled) {
11420                 list = new ArrayList<>(mSettings.getPackagesLocked().size());
11421                 for (PackageSetting ps : mSettings.getPackagesLocked().values()) {
11422                     ApplicationInfo ai;
11423                     int effectiveFlags = flags;
11424                     if (ps.isSystem()) {
11425                         effectiveFlags |= PackageManager.MATCH_ANY_USER;
11426                     }
11427                     if (ps.pkg != null) {
11428                         if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
11429                             continue;
11430                         }
11431                         if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
11432                             continue;
11433                         }
11434                         ai = PackageInfoUtils.generateApplicationInfo(ps.pkg, effectiveFlags,
11435                                 ps.readUserState(userId), userId, ps);
11436                         if (ai != null) {
11437                             ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
11438                         }
11439                     } else {
11440                         // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
11441                         // and already converts to externally visible package name
11442                         ai = generateApplicationInfoFromSettingsLPw(ps.name,
11443                                 effectiveFlags, callingUid, userId);
11444                     }
11445                     if (ai != null) {
11446                         list.add(ai);
11447                     }
11448                 }
11449             } else {
11450                 list = new ArrayList<>(mPackages.size());
11451                 for (AndroidPackage p : mPackages.values()) {
11452                     final PackageSetting ps = getPackageSetting(p.getPackageName());
11453                     if (ps != null) {
11454                         if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
11455                             continue;
11456                         }
11457                         if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
11458                             continue;
11459                         }
11460                         ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(p, flags,
11461                                 ps.readUserState(userId), userId, ps);
11462                         if (ai != null) {
11463                             ai.packageName = resolveExternalPackageNameLPr(p);
11464                             list.add(ai);
11465                         }
11466                     }
11467                 }
11468             }
11469 
11470             return list;
11471         }
11472     }
11473 
11474     @Override
getInstantApps(int userId)11475     public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
11476         if (HIDE_EPHEMERAL_APIS) {
11477             return null;
11478         }
11479         if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
11480             mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
11481                     "getEphemeralApplications");
11482         }
11483         enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
11484                 false /* checkShell */, "getEphemeralApplications");
11485         synchronized (mLock) {
11486             List<InstantAppInfo> instantApps = mInstantAppRegistry
11487                     .getInstantAppsLPr(userId);
11488             if (instantApps != null) {
11489                 return new ParceledListSlice<>(instantApps);
11490             }
11491         }
11492         return null;
11493     }
11494 
11495     @Override
isInstantApp(String packageName, int userId)11496     public boolean isInstantApp(String packageName, int userId) {
11497         return mComputer.isInstantApp(packageName, userId);
11498     }
11499 
isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid)11500     private boolean isInstantAppInternal(String packageName, @UserIdInt int userId,
11501             int callingUid) {
11502         return mComputer.isInstantAppInternal(packageName, userId,
11503                 callingUid);
11504     }
11505 
11506     @Override
getInstantAppCookie(String packageName, int userId)11507     public byte[] getInstantAppCookie(String packageName, int userId) {
11508         if (HIDE_EPHEMERAL_APIS) {
11509             return null;
11510         }
11511 
11512         enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
11513                 false /* checkShell */, "getInstantAppCookie");
11514         if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
11515             return null;
11516         }
11517         synchronized (mLock) {
11518             return mInstantAppRegistry.getInstantAppCookieLPw(
11519                     packageName, userId);
11520         }
11521     }
11522 
11523     @Override
setInstantAppCookie(String packageName, byte[] cookie, int userId)11524     public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
11525         if (HIDE_EPHEMERAL_APIS) {
11526             return true;
11527         }
11528 
11529         enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
11530                 true /* checkShell */, "setInstantAppCookie");
11531         if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
11532             return false;
11533         }
11534         synchronized (mLock) {
11535             return mInstantAppRegistry.setInstantAppCookieLPw(
11536                     packageName, cookie, userId);
11537         }
11538     }
11539 
11540     @Override
getInstantAppIcon(String packageName, int userId)11541     public Bitmap getInstantAppIcon(String packageName, int userId) {
11542         if (HIDE_EPHEMERAL_APIS) {
11543             return null;
11544         }
11545 
11546         if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
11547             mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
11548                     "getInstantAppIcon");
11549         }
11550         enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
11551                 false /* checkShell */, "getInstantAppIcon");
11552 
11553         synchronized (mLock) {
11554             return mInstantAppRegistry.getInstantAppIconLPw(
11555                     packageName, userId);
11556         }
11557     }
11558 
isCallerSameApp(String packageName, int uid)11559     private boolean isCallerSameApp(String packageName, int uid) {
11560         return mComputer.isCallerSameApp(packageName, uid);
11561     }
11562 
11563     @Override
getPersistentApplications(int flags)11564     public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
11565         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
11566             return ParceledListSlice.emptyList();
11567         }
11568         return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
11569     }
11570 
getPersistentApplicationsInternal(int flags)11571     private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
11572         final ArrayList<ApplicationInfo> finalList = new ArrayList<>();
11573 
11574         // reader
11575         synchronized (mLock) {
11576             final int numPackages = mPackages.size();
11577             final int userId = UserHandle.getCallingUserId();
11578             for (int index = 0; index < numPackages; index++) {
11579                 final AndroidPackage p = mPackages.valueAt(index);
11580 
11581                 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
11582                         && !p.isDirectBootAware();
11583                 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
11584                         && p.isDirectBootAware();
11585 
11586                 if (p.isPersistent()
11587                         && (!mSafeMode || p.isSystem())
11588                         && (matchesUnaware || matchesAware)) {
11589                     PackageSetting ps = mSettings.getPackageLPr(p.getPackageName());
11590                     if (ps != null) {
11591                         ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(p, flags,
11592                                 ps.readUserState(userId), userId, ps);
11593                         if (ai != null) {
11594                             finalList.add(ai);
11595                         }
11596                     }
11597                 }
11598             }
11599         }
11600 
11601         return finalList;
11602     }
11603 
11604     @Override
resolveContentProvider(String name, int flags, int userId)11605     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
11606         return resolveContentProviderInternal(name, flags, userId);
11607     }
11608 
resolveContentProvider(String name, int flags, int userId, int callingUid)11609     public ProviderInfo resolveContentProvider(String name, int flags, int userId, int callingUid) {
11610         return resolveContentProviderInternal(name, flags, userId, callingUid);
11611     }
11612 
resolveContentProviderInternal(String name, int flags, int userId)11613     private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
11614         return resolveContentProviderInternal(name, flags, userId, Binder.getCallingUid());
11615     }
11616 
resolveContentProviderInternal(String name, int flags, int userId, int callingUid)11617     private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId,
11618             int callingUid) {
11619         if (!mUserManager.exists(userId)) return null;
11620         flags = updateFlagsForComponent(flags, userId);
11621         final ProviderInfo providerInfo = mComponentResolver.queryProvider(name, flags, userId);
11622         boolean checkedGrants = false;
11623         if (providerInfo != null) {
11624             // Looking for cross-user grants before enforcing the typical cross-users permissions
11625             if (userId != UserHandle.getUserId(callingUid)) {
11626                 final UriGrantsManagerInternal ugmInternal =
11627                         mInjector.getLocalService(UriGrantsManagerInternal.class);
11628                 checkedGrants =
11629                         ugmInternal.checkAuthorityGrants(callingUid, providerInfo, userId, true);
11630             }
11631         }
11632         if (!checkedGrants) {
11633             enforceCrossUserPermission(callingUid, userId, false, false, "resolveContentProvider");
11634         }
11635         if (providerInfo == null) {
11636             return null;
11637         }
11638         synchronized (mLock) {
11639             if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
11640                 return null;
11641             }
11642             final PackageSetting ps = mSettings.getPackageLPr(providerInfo.packageName);
11643             final ComponentName component =
11644                     new ComponentName(providerInfo.packageName, providerInfo.name);
11645             if (shouldFilterApplicationLocked(ps, callingUid, component, TYPE_PROVIDER, userId)) {
11646                 return null;
11647             }
11648             return providerInfo;
11649         }
11650     }
11651 
11652     /**
11653      * @deprecated
11654      */
11655     @Deprecated
querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo)11656     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
11657         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
11658             return;
11659         }
11660         final List<String> names = new ArrayList<>();
11661         final List<ProviderInfo> infos = new ArrayList<>();
11662         final int callingUserId = UserHandle.getCallingUserId();
11663         mComponentResolver.querySyncProviders(
11664                 names, infos, mSafeMode, callingUserId);
11665         synchronized (mLock) {
11666             for (int i = infos.size() - 1; i >= 0; i--) {
11667                 final ProviderInfo providerInfo = infos.get(i);
11668                 final PackageSetting ps = mSettings.getPackageLPr(providerInfo.packageName);
11669                 final ComponentName component =
11670                         new ComponentName(providerInfo.packageName, providerInfo.name);
11671                 if (!shouldFilterApplicationLocked(ps, Binder.getCallingUid(), component,
11672                         TYPE_PROVIDER, callingUserId)) {
11673                     continue;
11674                 }
11675                 infos.remove(i);
11676                 names.remove(i);
11677             }
11678         }
11679         if (!names.isEmpty()) {
11680             outNames.addAll(names);
11681         }
11682         if (!infos.isEmpty()) {
11683             outInfo.addAll(infos);
11684         }
11685     }
11686 
11687     @Override
queryContentProviders(String processName, int uid, int flags, String metaDataKey)11688     public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
11689             int uid, int flags, String metaDataKey) {
11690         final int callingUid = Binder.getCallingUid();
11691         final int userId = processName != null ? UserHandle.getUserId(uid)
11692                 : UserHandle.getCallingUserId();
11693         if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
11694         flags = updateFlagsForComponent(flags, userId);
11695         ArrayList<ProviderInfo> finalList = null;
11696         final List<ProviderInfo> matchList =
11697                 mComponentResolver.queryProviders(processName, metaDataKey, uid, flags, userId);
11698         final int listSize = (matchList == null ? 0 : matchList.size());
11699         synchronized (mLock) {
11700             for (int i = 0; i < listSize; i++) {
11701                 final ProviderInfo providerInfo = matchList.get(i);
11702                 if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
11703                     continue;
11704                 }
11705                 final PackageSetting ps = mSettings.getPackageLPr(providerInfo.packageName);
11706                 final ComponentName component =
11707                         new ComponentName(providerInfo.packageName, providerInfo.name);
11708                 if (shouldFilterApplicationLocked(
11709                         ps, callingUid, component, TYPE_PROVIDER, userId)) {
11710                     continue;
11711                 }
11712                 if (finalList == null) {
11713                     finalList = new ArrayList<>(listSize - i);
11714                 }
11715                 finalList.add(providerInfo);
11716             }
11717         }
11718 
11719         if (finalList != null) {
11720             finalList.sort(sProviderInitOrderSorter);
11721             return new ParceledListSlice<>(finalList);
11722         }
11723 
11724         return ParceledListSlice.emptyList();
11725     }
11726 
11727     @Override
getInstrumentationInfo(ComponentName component, int flags)11728     public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
11729         // reader
11730         synchronized (mLock) {
11731             final int callingUid = Binder.getCallingUid();
11732             final int callingUserId = UserHandle.getUserId(callingUid);
11733             String packageName = component.getPackageName();
11734             final PackageSetting ps = mSettings.getPackageLPr(packageName);
11735             AndroidPackage pkg = mPackages.get(packageName);
11736             if (ps == null || pkg == null) return null;
11737             if (shouldFilterApplicationLocked(
11738                     ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
11739                 return null;
11740             }
11741             final ParsedInstrumentation i = mInstrumentation.get(component);
11742             return PackageInfoUtils.generateInstrumentationInfo(i, pkg, flags, callingUserId, ps);
11743         }
11744     }
11745 
11746     @Override
queryInstrumentation( String targetPackage, int flags)11747     public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
11748             String targetPackage, int flags) {
11749         final int callingUid = Binder.getCallingUid();
11750         final int callingUserId = UserHandle.getUserId(callingUid);
11751         synchronized (mLock) {
11752             final PackageSetting ps = mSettings.getPackageLPr(targetPackage);
11753             if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
11754                 return ParceledListSlice.emptyList();
11755             }
11756         }
11757         return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags,
11758                 callingUserId));
11759     }
11760 
queryInstrumentationInternal(String targetPackage, int flags, int userId)11761     private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
11762             int flags, int userId) {
11763         ArrayList<InstrumentationInfo> finalList = new ArrayList<>();
11764 
11765         // reader
11766         synchronized (mLock) {
11767             final int numInstrumentations = mInstrumentation.size();
11768             for (int index = 0; index < numInstrumentations; index++) {
11769                 final ParsedInstrumentation p = mInstrumentation.valueAt(index);
11770                 if (targetPackage == null
11771                         || targetPackage.equals(p.getTargetPackage())) {
11772                     String packageName = p.getPackageName();
11773                     AndroidPackage pkg = mPackages.get(packageName);
11774                     PackageSetting pkgSetting = getPackageSetting(packageName);
11775                     if (pkg != null) {
11776                         InstrumentationInfo ii = PackageInfoUtils.generateInstrumentationInfo(p,
11777                                 pkg, flags, userId, pkgSetting);
11778                         if (ii != null) {
11779                             finalList.add(ii);
11780                         }
11781                     }
11782                 }
11783             }
11784         }
11785 
11786         return finalList;
11787     }
11788 
scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags, long currentTime, PackageParser2 packageParser, ExecutorService executorService)11789     private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags,
11790             long currentTime, PackageParser2 packageParser, ExecutorService executorService) {
11791         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
11792         try {
11793             scanDirLI(scanDir, parseFlags, scanFlags, currentTime, packageParser, executorService);
11794         } finally {
11795             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11796         }
11797     }
11798 
scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime, PackageParser2 packageParser, ExecutorService executorService)11799     private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime,
11800             PackageParser2 packageParser, ExecutorService executorService) {
11801         final File[] files = scanDir.listFiles();
11802         if (ArrayUtils.isEmpty(files)) {
11803             Log.d(TAG, "No files in app dir " + scanDir);
11804             return;
11805         }
11806 
11807         if (DEBUG_PACKAGE_SCANNING) {
11808             Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
11809                     + " flags=0x" + Integer.toHexString(parseFlags));
11810         }
11811 
11812         ParallelPackageParser parallelPackageParser =
11813                 new ParallelPackageParser(packageParser, executorService);
11814 
11815         // Submit files for parsing in parallel
11816         int fileCount = 0;
11817         for (File file : files) {
11818             final boolean isPackage = (isApkFile(file) || file.isDirectory())
11819                     && !PackageInstallerService.isStageName(file.getName());
11820             if (!isPackage) {
11821                 // Ignore entries which are not packages
11822                 continue;
11823             }
11824             parallelPackageParser.submit(file, parseFlags);
11825             fileCount++;
11826         }
11827 
11828         // Process results one by one
11829         for (; fileCount > 0; fileCount--) {
11830             ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
11831             Throwable throwable = parseResult.throwable;
11832             int errorCode = PackageManager.INSTALL_SUCCEEDED;
11833             String errorMsg = null;
11834 
11835             if (throwable == null) {
11836                 // TODO(toddke): move lower in the scan chain
11837                 // Static shared libraries have synthetic package names
11838                 if (parseResult.parsedPackage.isStaticSharedLibrary()) {
11839                     renameStaticSharedLibraryPackage(parseResult.parsedPackage);
11840                 }
11841                 try {
11842                     addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags,
11843                             currentTime, null);
11844                 } catch (PackageManagerException e) {
11845                     errorCode = e.error;
11846                     errorMsg = "Failed to scan " + parseResult.scanFile + ": " + e.getMessage();
11847                     Slog.w(TAG, errorMsg);
11848                 }
11849             } else if (throwable instanceof PackageParserException) {
11850                 PackageParserException e = (PackageParserException)
11851                         throwable;
11852                 errorCode = e.error;
11853                 errorMsg = "Failed to parse " + parseResult.scanFile + ": " + e.getMessage();
11854                 Slog.w(TAG, errorMsg);
11855             } else {
11856                 throw new IllegalStateException("Unexpected exception occurred while parsing "
11857                         + parseResult.scanFile, throwable);
11858             }
11859 
11860             if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0 && errorCode != INSTALL_SUCCEEDED) {
11861                 mApexManager.reportErrorWithApkInApex(scanDir.getAbsolutePath(), errorMsg);
11862             }
11863 
11864             // Delete invalid userdata apps
11865             if ((scanFlags & SCAN_AS_SYSTEM) == 0
11866                     && errorCode != PackageManager.INSTALL_SUCCEEDED) {
11867                 logCriticalInfo(Log.WARN,
11868                         "Deleting invalid package at " + parseResult.scanFile);
11869                 removeCodePathLI(parseResult.scanFile);
11870             }
11871         }
11872     }
11873 
reportSettingsProblem(int priority, String msg)11874     public static void reportSettingsProblem(int priority, String msg) {
11875         logCriticalInfo(priority, msg);
11876     }
11877 
collectCertificatesLI(PackageSetting ps, ParsedPackage parsedPackage, boolean forceCollect, boolean skipVerify)11878     private void collectCertificatesLI(PackageSetting ps, ParsedPackage parsedPackage,
11879             boolean forceCollect, boolean skipVerify) throws PackageManagerException {
11880         // When upgrading from pre-N MR1, verify the package time stamp using the package
11881         // directory and not the APK file.
11882         final long lastModifiedTime = mIsPreNMR1Upgrade
11883                 ? new File(parsedPackage.getPath()).lastModified()
11884                 : getLastModifiedTime(parsedPackage);
11885         final VersionInfo settingsVersionForPackage = getSettingsVersionForPackage(parsedPackage);
11886         if (ps != null && !forceCollect
11887                 && ps.getPathString().equals(parsedPackage.getPath())
11888                 && ps.timeStamp == lastModifiedTime
11889                 && !isCompatSignatureUpdateNeeded(settingsVersionForPackage)
11890                 && !isRecoverSignatureUpdateNeeded(settingsVersionForPackage)) {
11891             if (ps.signatures.mSigningDetails.signatures != null
11892                     && ps.signatures.mSigningDetails.signatures.length != 0
11893                     && ps.signatures.mSigningDetails.signatureSchemeVersion
11894                             != SignatureSchemeVersion.UNKNOWN) {
11895                 // Optimization: reuse the existing cached signing data
11896                 // if the package appears to be unchanged.
11897                 parsedPackage.setSigningDetails(
11898                         new PackageParser.SigningDetails(ps.signatures.mSigningDetails));
11899                 return;
11900             }
11901 
11902             Slog.w(TAG, "PackageSetting for " + ps.name
11903                     + " is missing signatures.  Collecting certs again to recover them.");
11904         } else {
11905             Slog.i(TAG, parsedPackage.getPath() + " changed; collecting certs"
11906                     + (forceCollect ? " (forced)" : ""));
11907         }
11908 
11909         try {
11910             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
11911             parsedPackage.setSigningDetails(
11912                     ParsingPackageUtils.getSigningDetails(parsedPackage, skipVerify));
11913         } catch (PackageParserException e) {
11914             throw PackageManagerException.from(e);
11915         } finally {
11916             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11917         }
11918     }
11919 
11920     /**
11921      * Clear the package profile if this was an upgrade and the package
11922      * version was updated.
11923      */
maybeClearProfilesForUpgradesLI( @ullable PackageSetting originalPkgSetting, @NonNull AndroidPackage pkg)11924     private void maybeClearProfilesForUpgradesLI(
11925             @Nullable PackageSetting originalPkgSetting,
11926             @NonNull AndroidPackage pkg) {
11927         if (originalPkgSetting == null || !isDeviceUpgrading()) {
11928           return;
11929         }
11930         if (originalPkgSetting.versionCode == pkg.getVersionCode()) {
11931           return;
11932         }
11933 
11934         clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
11935         if (DEBUG_INSTALL) {
11936             Slog.d(TAG, originalPkgSetting.name
11937                   + " clear profile due to version change "
11938                   + originalPkgSetting.versionCode + " != "
11939                   + pkg.getVersionCode());
11940         }
11941     }
11942 
11943     /**
11944      *  Traces a package scan.
11945      *  @see #scanPackageLI(File, int, int, long, UserHandle)
11946      */
11947     @GuardedBy({"mInstallLock", "mLock"})
scanPackageTracedLI(File scanFile, final int parseFlags, int scanFlags, long currentTime, UserHandle user)11948     private AndroidPackage scanPackageTracedLI(File scanFile, final int parseFlags,
11949             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
11950         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
11951         try {
11952             return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
11953         } finally {
11954             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11955         }
11956     }
11957 
11958     /**
11959      *  Scans a package and returns the newly parsed package.
11960      *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
11961      */
11962     @GuardedBy({"mInstallLock", "mLock"})
scanPackageLI(File scanFile, int parseFlags, int scanFlags, long currentTime, UserHandle user)11963     private AndroidPackage scanPackageLI(File scanFile, int parseFlags, int scanFlags,
11964             long currentTime, UserHandle user) throws PackageManagerException {
11965         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
11966 
11967         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
11968         final ParsedPackage parsedPackage;
11969         try (PackageParser2 pp = mInjector.getScanningPackageParser()) {
11970             parsedPackage = pp.parsePackage(scanFile, parseFlags, false);
11971         } catch (PackageParserException e) {
11972             throw PackageManagerException.from(e);
11973         } finally {
11974             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11975         }
11976 
11977         // Static shared libraries have synthetic package names
11978         if (parsedPackage.isStaticSharedLibrary()) {
11979             renameStaticSharedLibraryPackage(parsedPackage);
11980         }
11981 
11982         return addForInitLI(parsedPackage, parseFlags, scanFlags, currentTime, user);
11983     }
11984 
11985     /**
11986      * Returns if forced apk verification can be skipped for the whole package, including splits.
11987      */
canSkipForcedPackageVerification(AndroidPackage pkg)11988     private boolean canSkipForcedPackageVerification(AndroidPackage pkg) {
11989         if (!canSkipForcedApkVerification(pkg.getBaseApkPath())) {
11990             return false;
11991         }
11992         // TODO: Allow base and splits to be verified individually.
11993         String[] splitCodePaths = pkg.getSplitCodePaths();
11994         if (!ArrayUtils.isEmpty(splitCodePaths)) {
11995             for (int i = 0; i < splitCodePaths.length; i++) {
11996                 if (!canSkipForcedApkVerification(splitCodePaths[i])) {
11997                     return false;
11998                 }
11999             }
12000         }
12001         return true;
12002     }
12003 
12004     /**
12005      * Returns if forced apk verification can be skipped, depending on current FSVerity setup and
12006      * whether the apk contains signed root hash.  Note that the signer's certificate still needs to
12007      * match one in a trusted source, and should be done separately.
12008      */
canSkipForcedApkVerification(String apkPath)12009     private boolean canSkipForcedApkVerification(String apkPath) {
12010         if (!PackageManagerServiceUtils.isLegacyApkVerityEnabled()) {
12011             return VerityUtils.hasFsverity(apkPath);
12012         }
12013 
12014         try {
12015             final byte[] rootHashObserved = VerityUtils.generateApkVerityRootHash(apkPath);
12016             if (rootHashObserved == null) {
12017                 return false;  // APK does not contain Merkle tree root hash.
12018             }
12019             synchronized (mInstallLock) {
12020                 // Returns whether the observed root hash matches what kernel has.
12021                 mInstaller.assertFsverityRootHashMatches(apkPath, rootHashObserved);
12022                 return true;
12023             }
12024         } catch (InstallerException | IOException | DigestException |
12025                 NoSuchAlgorithmException e) {
12026             Slog.w(TAG, "Error in fsverity check. Fallback to full apk verification.", e);
12027         }
12028         return false;
12029     }
12030 
12031     /**
12032      * Adds a new package to the internal data structures during platform initialization.
12033      * <p>After adding, the package is known to the system and available for querying.
12034      * <p>For packages located on the device ROM [eg. packages located in /system, /vendor,
12035      * etc...], additional checks are performed. Basic verification [such as ensuring
12036      * matching signatures, checking version codes, etc...] occurs if the package is
12037      * identical to a previously known package. If the package fails a signature check,
12038      * the version installed on /data will be removed. If the version of the new package
12039      * is less than or equal than the version on /data, it will be ignored.
12040      * <p>Regardless of the package location, the results are applied to the internal
12041      * structures and the package is made available to the rest of the system.
12042      * <p>NOTE: The return value should be removed. It's the passed in package object.
12043      */
12044     @GuardedBy({"mInstallLock", "mLock"})
addForInitLI(ParsedPackage parsedPackage, @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime, @Nullable UserHandle user)12045     private AndroidPackage addForInitLI(ParsedPackage parsedPackage,
12046             @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
12047             @Nullable UserHandle user)
12048                     throws PackageManagerException {
12049         final boolean scanSystemPartition =
12050                 (parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) != 0;
12051         final String renamedPkgName;
12052         final PackageSetting disabledPkgSetting;
12053         final boolean isSystemPkgUpdated;
12054         final boolean pkgAlreadyExists;
12055         PackageSetting pkgSetting;
12056 
12057         synchronized (mLock) {
12058             renamedPkgName = mSettings.getRenamedPackageLPr(parsedPackage.getRealPackage());
12059             final String realPkgName = getRealPackageName(parsedPackage, renamedPkgName);
12060             if (realPkgName != null) {
12061                 ensurePackageRenamed(parsedPackage, renamedPkgName);
12062             }
12063             final PackageSetting originalPkgSetting = getOriginalPackageLocked(parsedPackage,
12064                     renamedPkgName);
12065             final PackageSetting installedPkgSetting = mSettings.getPackageLPr(
12066                     parsedPackage.getPackageName());
12067             pkgSetting = originalPkgSetting == null ? installedPkgSetting : originalPkgSetting;
12068             pkgAlreadyExists = pkgSetting != null;
12069             final String disabledPkgName = pkgAlreadyExists
12070                     ? pkgSetting.name : parsedPackage.getPackageName();
12071             if (scanSystemPartition && !pkgAlreadyExists
12072                     && mSettings.getDisabledSystemPkgLPr(disabledPkgName) != null) {
12073                 // The updated-package data for /system apk remains inconsistently
12074                 // after the package data for /data apk is lost accidentally.
12075                 // To recover it, enable /system apk and install it as non-updated system app.
12076                 Slog.w(TAG, "Inconsistent package setting of updated system app for "
12077                         + disabledPkgName + ". To recover it, enable the system app"
12078                         + "and install it as non-updated system app.");
12079                 mSettings.removeDisabledSystemPackageLPw(disabledPkgName);
12080             }
12081             disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(disabledPkgName);
12082             isSystemPkgUpdated = disabledPkgSetting != null;
12083 
12084             if (DEBUG_INSTALL && isSystemPkgUpdated) {
12085                 Slog.d(TAG, "updatedPkg = " + disabledPkgSetting);
12086             }
12087 
12088             final SharedUserSetting sharedUserSetting = (parsedPackage.getSharedUserId() != null)
12089                     ? mSettings.getSharedUserLPw(parsedPackage.getSharedUserId(),
12090                             0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true)
12091                     : null;
12092             if (DEBUG_PACKAGE_SCANNING
12093                     && (parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0
12094                     && sharedUserSetting != null) {
12095                 Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId()
12096                         + " (uid=" + sharedUserSetting.userId + "):"
12097                         + " packages=" + sharedUserSetting.packages);
12098             }
12099 
12100             if (scanSystemPartition) {
12101                 if (isSystemPkgUpdated) {
12102                     // we're updating the disabled package, so, scan it as the package setting
12103                     boolean isPlatformPackage = mPlatformPackage != null
12104                             && Objects.equals(mPlatformPackage.getPackageName(),
12105                             parsedPackage.getPackageName());
12106                     final ScanRequest request = new ScanRequest(parsedPackage, sharedUserSetting,
12107                             null, disabledPkgSetting /* pkgSetting */,
12108                             null /* disabledPkgSetting */, null /* originalPkgSetting */,
12109                             null, parseFlags, scanFlags, isPlatformPackage, user, null);
12110                     applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, true);
12111                     final ScanResult scanResult =
12112                             scanPackageOnlyLI(request, mInjector, mFactoryTest, -1L);
12113                     if (scanResult.existingSettingCopied && scanResult.request.pkgSetting != null) {
12114                         scanResult.request.pkgSetting.updateFrom(scanResult.pkgSetting);
12115                     }
12116                 }
12117             }
12118         }
12119 
12120         final boolean newPkgChangedPaths = pkgAlreadyExists
12121                 && !pkgSetting.getPathString().equals(parsedPackage.getPath());
12122         final boolean newPkgVersionGreater =
12123                 pkgAlreadyExists && parsedPackage.getLongVersionCode() > pkgSetting.versionCode;
12124         final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
12125                 && newPkgChangedPaths && newPkgVersionGreater;
12126         if (isSystemPkgBetter) {
12127             // The version of the application on /system is greater than the version on
12128             // /data. Switch back to the application on /system.
12129             // It's safe to assume the application on /system will correctly scan. If not,
12130             // there won't be a working copy of the application.
12131             synchronized (mLock) {
12132                 // just remove the loaded entries from package lists
12133                 mPackages.remove(pkgSetting.name);
12134             }
12135 
12136             logCriticalInfo(Log.WARN,
12137                     "System package updated;"
12138                     + " name: " + pkgSetting.name
12139                     + "; " + pkgSetting.versionCode + " --> " + parsedPackage.getLongVersionCode()
12140                     + "; " + pkgSetting.getPathString()
12141                             + " --> " + parsedPackage.getPath());
12142 
12143             final InstallArgs args = createInstallArgsForExisting(
12144                     pkgSetting.getPathString(), getAppDexInstructionSets(
12145                             pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString));
12146             args.cleanUpResourcesLI();
12147             synchronized (mLock) {
12148                 mSettings.enableSystemPackageLPw(pkgSetting.name);
12149             }
12150         }
12151 
12152         // The version of the application on the /system partition is less than or
12153         // equal to the version on the /data partition. Throw an exception and use
12154         // the application already installed on the /data partition.
12155         if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {
12156             // In the case of a skipped package, commitReconciledScanResultLocked is not called to
12157             // add the object to the "live" data structures, so this is the final mutation step
12158             // for the package. Which means it needs to be finalized here to cache derived fields.
12159             // This is relevant for cases where the disabled system package is used for flags or
12160             // other metadata.
12161             ((ParsedPackage) parsedPackage).hideAsFinal();
12162             throw new PackageManagerException(Log.WARN, "Package " + parsedPackage.getPackageName()
12163                     + " at " + parsedPackage.getPath() + " ignored: updated version "
12164                     + pkgSetting.versionCode + " better than this "
12165                     + parsedPackage.getLongVersionCode());
12166         }
12167 
12168         // Verify certificates against what was last scanned. Force re-collecting certificate in two
12169         // special cases:
12170         // 1) when scanning system, force re-collect only if system is upgrading.
12171         // 2) when scannning /data, force re-collect only if the app is privileged (updated from
12172         // preinstall, or treated as privileged, e.g. due to shared user ID).
12173         final boolean forceCollect = scanSystemPartition ? mIsUpgrade
12174                 : PackageManagerServiceUtils.isApkVerificationForced(pkgSetting);
12175         if (DEBUG_VERIFY && forceCollect) {
12176             Slog.d(TAG, "Force collect certificate of " + parsedPackage.getPackageName());
12177         }
12178 
12179         // Full APK verification can be skipped during certificate collection, only if the file is
12180         // in verified partition, or can be verified on access (when apk verity is enabled). In both
12181         // cases, only data in Signing Block is verified instead of the whole file.
12182         // TODO(b/136132412): skip for Incremental installation
12183         final boolean skipVerify = scanSystemPartition
12184                 || (forceCollect && canSkipForcedPackageVerification(parsedPackage));
12185         collectCertificatesLI(pkgSetting, parsedPackage, forceCollect, skipVerify);
12186 
12187         // Reset profile if the application version is changed
12188         maybeClearProfilesForUpgradesLI(pkgSetting, parsedPackage);
12189 
12190         /*
12191          * A new system app appeared, but we already had a non-system one of the
12192          * same name installed earlier.
12193          */
12194         boolean shouldHideSystemApp = false;
12195         // A new application appeared on /system, but, we already have a copy of
12196         // the application installed on /data.
12197         if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists
12198                 && !pkgSetting.isSystem()) {
12199 
12200             if (!parsedPackage.getSigningDetails()
12201                     .checkCapability(pkgSetting.signatures.mSigningDetails,
12202                     PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)
12203                             && !pkgSetting.signatures.mSigningDetails.checkCapability(
12204                                     parsedPackage.getSigningDetails(),
12205                                     PackageParser.SigningDetails.CertCapabilities.ROLLBACK)) {
12206                 logCriticalInfo(Log.WARN,
12207                         "System package signature mismatch;"
12208                         + " name: " + pkgSetting.name);
12209                 try (@SuppressWarnings("unused") PackageFreezer freezer = freezePackage(
12210                         parsedPackage.getPackageName(),
12211                         "scanPackageInternalLI")) {
12212                     deletePackageLIF(parsedPackage.getPackageName(), null, true,
12213                             mUserManager.getUserIds(), 0, null, false, null);
12214                 }
12215                 pkgSetting = null;
12216             } else if (newPkgVersionGreater) {
12217                 // The application on /system is newer than the application on /data.
12218                 // Simply remove the application on /data [keeping application data]
12219                 // and replace it with the version on /system.
12220                 logCriticalInfo(Log.WARN,
12221                         "System package enabled;"
12222                                 + " name: " + pkgSetting.name
12223                                 + "; " + pkgSetting.versionCode + " --> "
12224                                 + parsedPackage.getLongVersionCode()
12225                                 + "; " + pkgSetting.getPathString() + " --> "
12226                                 + parsedPackage.getPath());
12227                 InstallArgs args = createInstallArgsForExisting(
12228                         pkgSetting.getPathString(), getAppDexInstructionSets(
12229                                 pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString));
12230                 synchronized (mInstallLock) {
12231                     args.cleanUpResourcesLI();
12232                 }
12233             } else {
12234                 // The application on /system is older than the application on /data. Hide
12235                 // the application on /system and the version on /data will be scanned later
12236                 // and re-added like an update.
12237                 shouldHideSystemApp = true;
12238                 logCriticalInfo(Log.INFO,
12239                         "System package disabled;"
12240                                 + " name: " + pkgSetting.name
12241                                 + "; old: " + pkgSetting.getPathString() + " @ "
12242                                 + pkgSetting.versionCode
12243                                 + "; new: " + parsedPackage.getPath() + " @ "
12244                                 + parsedPackage.getPath());
12245             }
12246         }
12247 
12248         final ScanResult scanResult = scanPackageNewLI(parsedPackage, parseFlags, scanFlags
12249                 | SCAN_UPDATE_SIGNATURE, currentTime, user, null);
12250         if (scanResult.success) {
12251             synchronized (mLock) {
12252                 boolean appIdCreated = false;
12253                 try {
12254                     final String pkgName = scanResult.pkgSetting.name;
12255                     final Map<String, ReconciledPackage> reconcileResult = reconcilePackagesLocked(
12256                             new ReconcileRequest(
12257                                     Collections.singletonMap(pkgName, scanResult),
12258                                     mSharedLibraries,
12259                                     mPackages,
12260                                     Collections.singletonMap(
12261                                             pkgName, getSettingsVersionForPackage(parsedPackage)),
12262                                     Collections.singletonMap(pkgName,
12263                                             getSharedLibLatestVersionSetting(scanResult))),
12264                             mSettings.getKeySetManagerService(), mInjector);
12265                     appIdCreated = optimisticallyRegisterAppId(scanResult);
12266                     commitReconciledScanResultLocked(
12267                             reconcileResult.get(pkgName), mUserManager.getUserIds());
12268                 } catch (PackageManagerException e) {
12269                     if (appIdCreated) {
12270                         cleanUpAppIdCreation(scanResult);
12271                     }
12272                     throw e;
12273                 }
12274             }
12275         }
12276 
12277         if (shouldHideSystemApp) {
12278             synchronized (mLock) {
12279                 mSettings.disableSystemPackageLPw(parsedPackage.getPackageName(), true);
12280             }
12281         }
12282         if (mIncrementalManager != null && isIncrementalPath(parsedPackage.getPath())) {
12283             if (pkgSetting != null && pkgSetting.isPackageLoading()) {
12284                 // Continue monitoring loading progress of active incremental packages
12285                 final IncrementalStatesCallback incrementalStatesCallback =
12286                         new IncrementalStatesCallback(parsedPackage.getPackageName(),
12287                                 UserHandle.getUid(UserHandle.USER_ALL, pkgSetting.appId),
12288                                 getInstalledUsers(pkgSetting, UserHandle.USER_ALL));
12289                 pkgSetting.setIncrementalStatesCallback(incrementalStatesCallback);
12290                 mIncrementalManager.registerLoadingProgressCallback(parsedPackage.getPath(),
12291                         new IncrementalProgressListener(parsedPackage.getPackageName()));
12292             }
12293         }
12294         return scanResult.pkgSetting.pkg;
12295     }
12296 
12297     // TODO:(b/135203078): Move to parsing
renameStaticSharedLibraryPackage(ParsedPackage parsedPackage)12298     private static void renameStaticSharedLibraryPackage(ParsedPackage parsedPackage) {
12299         // Derive the new package synthetic package name
12300         parsedPackage.setPackageName(toStaticSharedLibraryPackageName(
12301                 parsedPackage.getPackageName(), parsedPackage.getStaticSharedLibVersion()));
12302     }
12303 
toStaticSharedLibraryPackageName( String packageName, long libraryVersion)12304     private static String toStaticSharedLibraryPackageName(
12305             String packageName, long libraryVersion) {
12306         return packageName + STATIC_SHARED_LIB_DELIMITER + libraryVersion;
12307     }
12308 
fixProcessName(String defProcessName, String processName)12309     static String fixProcessName(String defProcessName, String processName) {
12310         if (processName == null) {
12311             return defProcessName;
12312         }
12313         return processName;
12314     }
12315 
12316     /**
12317      * Enforces that only the system UID or root's UID can call a method exposed
12318      * via Binder.
12319      *
12320      * @param message used as message if SecurityException is thrown
12321      * @throws SecurityException if the caller is not system or root
12322      */
enforceSystemOrRoot(String message)12323     private static void enforceSystemOrRoot(String message) {
12324         final int uid = Binder.getCallingUid();
12325         if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
12326             throw new SecurityException(message);
12327         }
12328     }
12329 
12330     /**
12331      * Enforces that only the system UID or root's UID or shell's UID can call
12332      * a method exposed via Binder.
12333      *
12334      * @param message used as message if SecurityException is thrown
12335      * @throws SecurityException if the caller is not system or shell
12336      */
enforceSystemOrRootOrShell(String message)12337     private static void enforceSystemOrRootOrShell(String message) {
12338         final int uid = Binder.getCallingUid();
12339         if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID && uid != Process.SHELL_UID) {
12340             throw new SecurityException(message);
12341         }
12342     }
12343 
12344     /**
12345      * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
12346      * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller.
12347      *
12348      * @param checkShell whether to prevent shell from access if there's a debugging restriction
12349      * @param message the message to log on security exception
12350      */
enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message)12351     void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
12352             boolean requireFullPermission, boolean checkShell, String message) {
12353         mComputer.enforceCrossUserPermission(callingUid, userId,
12354                 requireFullPermission, checkShell, message);
12355     }
12356 
12357     /**
12358      * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
12359      * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller.
12360      *
12361      * @param checkShell whether to prevent shell from access if there's a debugging restriction
12362      * @param requirePermissionWhenSameUser When {@code true}, still require the cross user
12363      *                                      permission to be held even if the callingUid and userId
12364      *                                      reference the same user.
12365      * @param message the message to log on security exception
12366      */
enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, String message)12367     private void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
12368             boolean requireFullPermission, boolean checkShell,
12369             boolean requirePermissionWhenSameUser, String message) {
12370         mComputer.enforceCrossUserPermission(callingUid, userId,
12371                 requireFullPermission, checkShell,
12372                 requirePermissionWhenSameUser, message);
12373     }
12374 
12375     /**
12376      * Checks if the request is from the system or an app that has the appropriate cross-user
12377      * permissions defined as follows:
12378      * <ul>
12379      * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li>
12380      * <li>INTERACT_ACROSS_USERS if the given {@code userId} is in a different profile group
12381      * to the caller.</li>
12382      * <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@code userId} is in the same profile
12383      * group as the caller.</li>
12384      * </ul>
12385      *
12386      * @param checkShell whether to prevent shell from access if there's a debugging restriction
12387      * @param message the message to log on security exception
12388      */
enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message)12389     private void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
12390             boolean requireFullPermission, boolean checkShell, String message) {
12391         mComputer.enforceCrossUserOrProfilePermission(callingUid, userId,
12392                 requireFullPermission, checkShell, message);
12393     }
12394 
isSameProfileGroup(@serIdInt int callerUserId, @UserIdInt int userId)12395     private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) {
12396         return mComputer.isSameProfileGroup(callerUserId, userId);
12397     }
12398 
buildInvalidCrossUserPermissionMessage(int callingUid, @UserIdInt int userId, String message, boolean requireFullPermission)12399     private static String buildInvalidCrossUserPermissionMessage(int callingUid,
12400             @UserIdInt int userId, String message, boolean requireFullPermission) {
12401         StringBuilder builder = new StringBuilder();
12402         if (message != null) {
12403             builder.append(message);
12404             builder.append(": ");
12405         }
12406         builder.append("UID ");
12407         builder.append(callingUid);
12408         builder.append(" requires ");
12409         builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12410         if (!requireFullPermission) {
12411             builder.append(" or ");
12412             builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12413         }
12414         builder.append(" to access user ");
12415         builder.append(userId);
12416         builder.append(".");
12417         return builder.toString();
12418     }
12419 
buildInvalidCrossUserOrProfilePermissionMessage(int callingUid, @UserIdInt int userId, String message, boolean requireFullPermission, boolean isSameProfileGroup)12420     private static String buildInvalidCrossUserOrProfilePermissionMessage(int callingUid,
12421             @UserIdInt int userId, String message, boolean requireFullPermission,
12422             boolean isSameProfileGroup) {
12423         StringBuilder builder = new StringBuilder();
12424         if (message != null) {
12425             builder.append(message);
12426             builder.append(": ");
12427         }
12428         builder.append("UID ");
12429         builder.append(callingUid);
12430         builder.append(" requires ");
12431         builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12432         if (!requireFullPermission) {
12433             builder.append(" or ");
12434             builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12435             if (isSameProfileGroup) {
12436                 builder.append(" or ");
12437                 builder.append(android.Manifest.permission.INTERACT_ACROSS_PROFILES);
12438             }
12439         }
12440         builder.append(" to access user ");
12441         builder.append(".");
12442         return builder.toString();
12443     }
12444 
12445     @Override
performFstrimIfNeeded()12446     public void performFstrimIfNeeded() {
12447         enforceSystemOrRoot("Only the system can request fstrim");
12448 
12449         // Before everything else, see whether we need to fstrim.
12450         try {
12451             IStorageManager sm = PackageHelper.getStorageManager();
12452             if (sm != null) {
12453                 boolean doTrim = false;
12454                 final long interval = android.provider.Settings.Global.getLong(
12455                         mContext.getContentResolver(),
12456                         android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
12457                         DEFAULT_MANDATORY_FSTRIM_INTERVAL);
12458                 if (interval > 0) {
12459                     final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
12460                     if (timeSinceLast > interval) {
12461                         doTrim = true;
12462                         Slog.w(TAG, "No disk maintenance in " + timeSinceLast
12463                                 + "; running immediately");
12464                     }
12465                 }
12466                 if (doTrim) {
12467                     final boolean dexOptDialogShown;
12468                     synchronized (mLock) {
12469                         dexOptDialogShown = mDexOptDialogShown;
12470                     }
12471                     if (!isFirstBoot() && dexOptDialogShown) {
12472                         try {
12473                             ActivityManager.getService().showBootMessage(
12474                                     mContext.getResources().getString(
12475                                             R.string.android_upgrading_fstrim), true);
12476                         } catch (RemoteException e) {
12477                         }
12478                     }
12479                     sm.runMaintenance();
12480                 }
12481             } else {
12482                 Slog.e(TAG, "storageManager service unavailable!");
12483             }
12484         } catch (RemoteException e) {
12485             // Can't happen; StorageManagerService is local
12486         }
12487     }
12488 
12489     @Override
updatePackagesIfNeeded()12490     public void updatePackagesIfNeeded() {
12491         enforceSystemOrRoot("Only the system can request package update");
12492 
12493         // We need to re-extract after an OTA.
12494         boolean causeUpgrade = isDeviceUpgrading();
12495 
12496         // First boot or factory reset.
12497         // Note: we also handle devices that are upgrading to N right now as if it is their
12498         //       first boot, as they do not have profile data.
12499         boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
12500 
12501         if (!causeUpgrade && !causeFirstBoot) {
12502             return;
12503         }
12504 
12505         List<PackageSetting> pkgSettings;
12506         synchronized (mLock) {
12507             pkgSettings = PackageManagerServiceUtils.getPackagesForDexopt(
12508                     mSettings.getPackagesLocked().values(), this);
12509         }
12510 
12511         List<AndroidPackage> pkgs = new ArrayList<>(pkgSettings.size());
12512         for (int index = 0; index < pkgSettings.size(); index++) {
12513             pkgs.add(pkgSettings.get(index).pkg);
12514         }
12515 
12516         final long startTime = System.nanoTime();
12517         final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
12518                     causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT_AFTER_OTA,
12519                     false /* bootComplete */);
12520 
12521         final int elapsedTimeSeconds =
12522                 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
12523 
12524         MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
12525         MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
12526         MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
12527         MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
12528         MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
12529     }
12530 
12531     /*
12532      * Return the prebuilt profile path given a package base code path.
12533      */
getPrebuildProfilePath(AndroidPackage pkg)12534     private static String getPrebuildProfilePath(AndroidPackage pkg) {
12535         return pkg.getBaseApkPath() + ".prof";
12536     }
12537 
12538     /**
12539      * Performs dexopt on the set of packages in {@code packages} and returns an int array
12540      * containing statistics about the invocation. The array consists of three elements,
12541      * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
12542      * and {@code numberOfPackagesFailed}.
12543      */
performDexOptUpgrade(List<AndroidPackage> pkgs, boolean showDialog, final int compilationReason, boolean bootComplete)12544     private int[] performDexOptUpgrade(List<AndroidPackage> pkgs, boolean showDialog,
12545             final int compilationReason, boolean bootComplete) {
12546 
12547         int numberOfPackagesVisited = 0;
12548         int numberOfPackagesOptimized = 0;
12549         int numberOfPackagesSkipped = 0;
12550         int numberOfPackagesFailed = 0;
12551         final int numberOfPackagesToDexopt = pkgs.size();
12552 
12553         for (AndroidPackage pkg : pkgs) {
12554             numberOfPackagesVisited++;
12555 
12556             boolean useProfileForDexopt = false;
12557 
12558             if ((isFirstBoot() || isDeviceUpgrading()) && pkg.isSystem()) {
12559                 // Copy over initial preopt profiles since we won't get any JIT samples for methods
12560                 // that are already compiled.
12561                 File profileFile = new File(getPrebuildProfilePath(pkg));
12562                 // Copy profile if it exists.
12563                 if (profileFile.exists()) {
12564                     try {
12565                         // We could also do this lazily before calling dexopt in
12566                         // PackageDexOptimizer to prevent this happening on first boot. The issue
12567                         // is that we don't have a good way to say "do this only once".
12568                         if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
12569                                 pkg.getUid(), pkg.getPackageName(),
12570                                 ArtManager.getProfileName(null))) {
12571                             Log.e(TAG, "Installer failed to copy system profile!");
12572                         } else {
12573                             // Disabled as this causes speed-profile compilation during first boot
12574                             // even if things are already compiled.
12575                             // useProfileForDexopt = true;
12576                         }
12577                     } catch (Exception e) {
12578                         Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
12579                                 e);
12580                     }
12581                 } else {
12582                     PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(
12583                             pkg.getPackageName());
12584                     // Handle compressed APKs in this path. Only do this for stubs with profiles to
12585                     // minimize the number off apps being speed-profile compiled during first boot.
12586                     // The other paths will not change the filter.
12587                     if (disabledPs != null && disabledPs.pkg.isStub()) {
12588                         // The package is the stub one, remove the stub suffix to get the normal
12589                         // package and APK names.
12590                         String systemProfilePath =
12591                                 getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
12592                         profileFile = new File(systemProfilePath);
12593                         // If we have a profile for a compressed APK, copy it to the reference
12594                         // location.
12595                         // Note that copying the profile here will cause it to override the
12596                         // reference profile every OTA even though the existing reference profile
12597                         // may have more data. We can't copy during decompression since the
12598                         // directories are not set up at that point.
12599                         if (profileFile.exists()) {
12600                             try {
12601                                 // We could also do this lazily before calling dexopt in
12602                                 // PackageDexOptimizer to prevent this happening on first boot. The
12603                                 // issue is that we don't have a good way to say "do this only
12604                                 // once".
12605                                 if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
12606                                         pkg.getUid(), pkg.getPackageName(),
12607                                         ArtManager.getProfileName(null))) {
12608                                     Log.e(TAG, "Failed to copy system profile for stub package!");
12609                                 } else {
12610                                     useProfileForDexopt = true;
12611                                 }
12612                             } catch (Exception e) {
12613                                 Log.e(TAG, "Failed to copy profile " +
12614                                         profileFile.getAbsolutePath() + " ", e);
12615                             }
12616                         }
12617                     }
12618                 }
12619             }
12620 
12621             if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
12622                 if (DEBUG_DEXOPT) {
12623                     Log.i(TAG, "Skipping update of non-optimizable app " + pkg.getPackageName());
12624                 }
12625                 numberOfPackagesSkipped++;
12626                 continue;
12627             }
12628 
12629             if (DEBUG_DEXOPT) {
12630                 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
12631                         numberOfPackagesToDexopt + ": " + pkg.getPackageName());
12632             }
12633 
12634             if (showDialog) {
12635                 try {
12636                     ActivityManager.getService().showBootMessage(
12637                             mContext.getResources().getString(R.string.android_upgrading_apk,
12638                                     numberOfPackagesVisited, numberOfPackagesToDexopt), true);
12639                 } catch (RemoteException e) {
12640                 }
12641                 synchronized (mLock) {
12642                     mDexOptDialogShown = true;
12643                 }
12644             }
12645 
12646             int pkgCompilationReason = compilationReason;
12647             if (useProfileForDexopt) {
12648                 // Use background dexopt mode to try and use the profile. Note that this does not
12649                 // guarantee usage of the profile.
12650                 pkgCompilationReason = PackageManagerService.REASON_BACKGROUND_DEXOPT;
12651             }
12652 
12653             if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
12654                 mArtManagerService.compileLayouts(pkg);
12655             }
12656 
12657             // checkProfiles is false to avoid merging profiles during boot which
12658             // might interfere with background compilation (b/28612421).
12659             // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
12660             // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
12661             // trade-off worth doing to save boot time work.
12662             int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
12663             if (compilationReason == REASON_FIRST_BOOT) {
12664                 // TODO: This doesn't cover the upgrade case, we should check for this too.
12665                 dexoptFlags |= DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE;
12666             }
12667             int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
12668                     pkg.getPackageName(),
12669                     pkgCompilationReason,
12670                     dexoptFlags));
12671 
12672             switch (primaryDexOptStaus) {
12673                 case PackageDexOptimizer.DEX_OPT_PERFORMED:
12674                     numberOfPackagesOptimized++;
12675                     break;
12676                 case PackageDexOptimizer.DEX_OPT_SKIPPED:
12677                     numberOfPackagesSkipped++;
12678                     break;
12679                 case PackageDexOptimizer.DEX_OPT_FAILED:
12680                     numberOfPackagesFailed++;
12681                     break;
12682                 default:
12683                     Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
12684                     break;
12685             }
12686         }
12687 
12688         return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
12689                 numberOfPackagesFailed };
12690     }
12691 
12692     @Override
notifyPackageUse(String packageName, int reason)12693     public void notifyPackageUse(String packageName, int reason) {
12694         synchronized (mLock) {
12695             final int callingUid = Binder.getCallingUid();
12696             final int callingUserId = UserHandle.getUserId(callingUid);
12697             if (getInstantAppPackageName(callingUid) != null) {
12698                 if (!isCallerSameApp(packageName, callingUid)) {
12699                     return;
12700                 }
12701             } else {
12702                 if (isInstantApp(packageName, callingUserId)) {
12703                     return;
12704                 }
12705             }
12706             notifyPackageUseLocked(packageName, reason);
12707         }
12708     }
12709 
12710     @GuardedBy("mLock")
notifyPackageUseLocked(String packageName, int reason)12711     private void notifyPackageUseLocked(String packageName, int reason) {
12712         final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
12713         if (pkgSetting == null) {
12714             return;
12715         }
12716         pkgSetting.getPkgState().setLastPackageUsageTimeInMills(reason, System.currentTimeMillis());
12717     }
12718 
12719     @Override
notifyDexLoad(String loadingPackageName, Map<String, String> classLoaderContextMap, String loaderIsa)12720     public void notifyDexLoad(String loadingPackageName, Map<String, String> classLoaderContextMap,
12721             String loaderIsa) {
12722         int callingUid = Binder.getCallingUid();
12723         if (PLATFORM_PACKAGE_NAME.equals(loadingPackageName) && callingUid != Process.SYSTEM_UID) {
12724             Slog.w(TAG, "Non System Server process reporting dex loads as system server. uid="
12725                     + callingUid);
12726             // Do not record dex loads from processes pretending to be system server.
12727             // Only the system server should be assigned the package "android", so reject calls
12728             // that don't satisfy the constraint.
12729             //
12730             // notifyDexLoad is a PM API callable from the app process. So in theory, apps could
12731             // craft calls to this API and pretend to be system server. Doing so poses no particular
12732             // danger for dex load reporting or later dexopt, however it is a sensible check to do
12733             // in order to verify the expectations.
12734             return;
12735         }
12736 
12737         int userId = UserHandle.getCallingUserId();
12738         ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
12739         if (ai == null) {
12740             Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
12741                 + loadingPackageName + ", user=" + userId);
12742             return;
12743         }
12744         mDexManager.notifyDexLoad(ai, classLoaderContextMap, loaderIsa, userId,
12745                 Process.isIsolated(callingUid));
12746     }
12747 
12748     @Override
registerDexModule(String packageName, String dexModulePath, boolean isSharedModule, IDexModuleRegisterCallback callback)12749     public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
12750             IDexModuleRegisterCallback callback) {
12751         int userId = UserHandle.getCallingUserId();
12752         ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
12753         DexManager.RegisterDexModuleResult result;
12754         if (ai == null) {
12755             Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
12756                      " calling user. package=" + packageName + ", user=" + userId);
12757             result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
12758         } else {
12759             result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
12760         }
12761 
12762         if (callback != null) {
12763             mHandler.post(() -> {
12764                 try {
12765                     callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
12766                 } catch (RemoteException e) {
12767                     Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
12768                 }
12769             });
12770         }
12771     }
12772 
12773     /**
12774      * Ask the package manager to perform a dex-opt with the given compiler filter.
12775      *
12776      * Note: exposed only for the shell command to allow moving packages explicitly to a
12777      *       definite state.
12778      */
12779     @Override
performDexOptMode(String packageName, boolean checkProfiles, String targetCompilerFilter, boolean force, boolean bootComplete, String splitName)12780     public boolean performDexOptMode(String packageName,
12781             boolean checkProfiles, String targetCompilerFilter, boolean force,
12782             boolean bootComplete, String splitName) {
12783         enforceSystemOrRootOrShell("performDexOptMode");
12784 
12785         int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
12786                 (force ? DexoptOptions.DEXOPT_FORCE : 0) |
12787                 (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
12788         return performDexOpt(new DexoptOptions(packageName, REASON_CMDLINE,
12789                 targetCompilerFilter, splitName, flags));
12790     }
12791 
12792     /**
12793      * Ask the package manager to perform a dex-opt with the given compiler filter on the
12794      * secondary dex files belonging to the given package.
12795      *
12796      * Note: exposed only for the shell command to allow moving packages explicitly to a
12797      *       definite state.
12798      */
12799     @Override
performDexOptSecondary(String packageName, String compilerFilter, boolean force)12800     public boolean performDexOptSecondary(String packageName, String compilerFilter,
12801             boolean force) {
12802         int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
12803                 DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
12804                 DexoptOptions.DEXOPT_BOOT_COMPLETE |
12805                 (force ? DexoptOptions.DEXOPT_FORCE : 0);
12806         return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
12807     }
12808 
performDexOpt(DexoptOptions options)12809     /*package*/ boolean performDexOpt(DexoptOptions options) {
12810         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
12811             return false;
12812         } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
12813             return false;
12814         }
12815 
12816         if (options.isDexoptOnlySecondaryDex()) {
12817             return mDexManager.dexoptSecondaryDex(options);
12818         } else {
12819             int dexoptStatus = performDexOptWithStatus(options);
12820             return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
12821         }
12822     }
12823 
12824     /**
12825      * Perform dexopt on the given package and return one of following result:
12826      *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
12827      *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
12828      *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
12829      */
performDexOptWithStatus(DexoptOptions options)12830     /* package */ int performDexOptWithStatus(DexoptOptions options) {
12831         return performDexOptTraced(options);
12832     }
12833 
performDexOptTraced(DexoptOptions options)12834     private int performDexOptTraced(DexoptOptions options) {
12835         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
12836         try {
12837             return performDexOptInternal(options);
12838         } finally {
12839             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12840         }
12841     }
12842 
12843     // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
12844     // if the package can now be considered up to date for the given filter.
performDexOptInternal(DexoptOptions options)12845     private int performDexOptInternal(DexoptOptions options) {
12846         AndroidPackage p;
12847         PackageSetting pkgSetting;
12848         synchronized (mLock) {
12849             p = mPackages.get(options.getPackageName());
12850             pkgSetting = mSettings.getPackageLPr(options.getPackageName());
12851             if (p == null || pkgSetting == null) {
12852                 // Package could not be found. Report failure.
12853                 return PackageDexOptimizer.DEX_OPT_FAILED;
12854             }
12855             mPackageUsage.maybeWriteAsync(mSettings.getPackagesLocked());
12856             mCompilerStats.maybeWriteAsync();
12857         }
12858         final long callingId = Binder.clearCallingIdentity();
12859         try {
12860             synchronized (mInstallLock) {
12861                 return performDexOptInternalWithDependenciesLI(p, pkgSetting, options);
12862             }
12863         } finally {
12864             Binder.restoreCallingIdentity(callingId);
12865         }
12866     }
12867 
getOptimizablePackages()12868     public ArraySet<String> getOptimizablePackages() {
12869         ArraySet<String> pkgs = new ArraySet<>();
12870         synchronized (mLock) {
12871             for (AndroidPackage p : mPackages.values()) {
12872                 if (PackageDexOptimizer.canOptimizePackage(p)) {
12873                     pkgs.add(p.getPackageName());
12874                 }
12875             }
12876         }
12877         if (AppHibernationService.isAppHibernationEnabled()) {
12878             AppHibernationManagerInternal appHibernationManager =
12879                     mInjector.getLocalService(AppHibernationManagerInternal.class);
12880             pkgs.removeIf(pkgName -> appHibernationManager.isHibernatingGlobally(pkgName));
12881         }
12882         return pkgs;
12883     }
12884 
performDexOptInternalWithDependenciesLI(AndroidPackage p, @NonNull PackageSetting pkgSetting, DexoptOptions options)12885     private int performDexOptInternalWithDependenciesLI(AndroidPackage p,
12886             @NonNull PackageSetting pkgSetting, DexoptOptions options) {
12887         // System server gets a special path.
12888         if (PLATFORM_PACKAGE_NAME.equals(p.getPackageName())) {
12889             return mDexManager.dexoptSystemServer(options);
12890         }
12891 
12892         // Select the dex optimizer based on the force parameter.
12893         // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
12894         //       allocate an object here.
12895         PackageDexOptimizer pdo = options.isForce()
12896                 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
12897                 : mPackageDexOptimizer;
12898 
12899         // Dexopt all dependencies first. Note: we ignore the return value and march on
12900         // on errors.
12901         // Note that we are going to call performDexOpt on those libraries as many times as
12902         // they are referenced in packages. When we do a batch of performDexOpt (for example
12903         // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
12904         // and the first package that uses the library will dexopt it. The
12905         // others will see that the compiled code for the library is up to date.
12906         Collection<SharedLibraryInfo> deps = findSharedLibraries(pkgSetting);
12907         final String[] instructionSets = getAppDexInstructionSets(
12908                 AndroidPackageUtils.getPrimaryCpuAbi(p, pkgSetting),
12909                 AndroidPackageUtils.getSecondaryCpuAbi(p, pkgSetting));
12910         if (!deps.isEmpty()) {
12911             DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
12912                     options.getCompilationReason(), options.getCompilerFilter(),
12913                     options.getSplitName(),
12914                     options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
12915             for (SharedLibraryInfo info : deps) {
12916                 AndroidPackage depPackage = null;
12917                 PackageSetting depPackageSetting = null;
12918                 synchronized (mLock) {
12919                     depPackage = mPackages.get(info.getPackageName());
12920                     depPackageSetting = mSettings.getPackageLPr(info.getPackageName());
12921                 }
12922                 if (depPackage != null && depPackageSetting != null) {
12923                     // TODO: Analyze and investigate if we (should) profile libraries.
12924                     pdo.performDexOpt(depPackage, depPackageSetting, instructionSets,
12925                             getOrCreateCompilerPackageStats(depPackage),
12926                             mDexManager.getPackageUseInfoOrDefault(depPackage.getPackageName()),
12927                             libraryOptions);
12928                 } else {
12929                     // TODO(ngeoffray): Support dexopting system shared libraries.
12930                 }
12931             }
12932         }
12933 
12934         return pdo.performDexOpt(p, pkgSetting, instructionSets,
12935                 getOrCreateCompilerPackageStats(p),
12936                 mDexManager.getPackageUseInfoOrDefault(p.getPackageName()), options);
12937     }
12938 
12939     /**
12940      * Reconcile the information we have about the secondary dex files belonging to
12941      * {@code packageName} and the actual dex files. For all dex files that were
12942      * deleted, update the internal records and delete the generated oat files.
12943      */
12944     @Override
reconcileSecondaryDexFiles(String packageName)12945     public void reconcileSecondaryDexFiles(String packageName) {
12946         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
12947             return;
12948         } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
12949             return;
12950         }
12951         mDexManager.reconcileSecondaryDexFiles(packageName);
12952     }
12953 
12954     // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
12955     // a reference there.
getDexManager()12956     /*package*/ DexManager getDexManager() {
12957         return mDexManager;
12958     }
12959 
12960     /**
12961      * Execute the background dexopt job immediately.
12962      */
12963     @Override
runBackgroundDexoptJob(@ullable List<String> packageNames)12964     public boolean runBackgroundDexoptJob(@Nullable List<String> packageNames) {
12965         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
12966             return false;
12967         }
12968         enforceSystemOrRootOrShell("runBackgroundDexoptJob");
12969         final long identity = Binder.clearCallingIdentity();
12970         try {
12971             return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
12972         } finally {
12973             Binder.restoreCallingIdentity(identity);
12974         }
12975     }
12976 
findSharedLibraries(PackageSetting pkgSetting)12977     private static List<SharedLibraryInfo> findSharedLibraries(PackageSetting pkgSetting) {
12978         if (!pkgSetting.getPkgState().getUsesLibraryInfos().isEmpty()) {
12979             ArrayList<SharedLibraryInfo> retValue = new ArrayList<>();
12980             Set<String> collectedNames = new HashSet<>();
12981             for (SharedLibraryInfo info : pkgSetting.getPkgState().getUsesLibraryInfos()) {
12982                 findSharedLibrariesRecursive(info, retValue, collectedNames);
12983             }
12984             return retValue;
12985         } else {
12986             return Collections.emptyList();
12987         }
12988     }
12989 
findSharedLibrariesRecursive(SharedLibraryInfo info, ArrayList<SharedLibraryInfo> collected, Set<String> collectedNames)12990     private static void findSharedLibrariesRecursive(SharedLibraryInfo info,
12991             ArrayList<SharedLibraryInfo> collected, Set<String> collectedNames) {
12992         if (!collectedNames.contains(info.getName())) {
12993             collectedNames.add(info.getName());
12994             collected.add(info);
12995 
12996             if (info.getDependencies() != null) {
12997                 for (SharedLibraryInfo dep : info.getDependencies()) {
12998                     findSharedLibrariesRecursive(dep, collected, collectedNames);
12999                 }
13000             }
13001         }
13002     }
13003 
findSharedNonSystemLibraries(PackageSetting pkgSetting)13004     List<PackageSetting> findSharedNonSystemLibraries(PackageSetting pkgSetting) {
13005         List<SharedLibraryInfo> deps = findSharedLibraries(pkgSetting);
13006         if (!deps.isEmpty()) {
13007             List<PackageSetting> retValue = new ArrayList<>();
13008             synchronized (mLock) {
13009                 for (SharedLibraryInfo info : deps) {
13010                     PackageSetting depPackageSetting =
13011                             mSettings.getPackageLPr(info.getPackageName());
13012                     if (depPackageSetting != null && depPackageSetting.pkg != null) {
13013                         retValue.add(depPackageSetting);
13014                     }
13015                 }
13016             }
13017             return retValue;
13018         } else {
13019             return Collections.emptyList();
13020         }
13021     }
13022 
13023     @Nullable
getSharedLibraryInfoLPr(String name, long version)13024     private SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version) {
13025         return mComputer.getSharedLibraryInfoLPr(name, version);
13026     }
13027 
13028     @Nullable
getSharedLibraryInfo(String name, long version, Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingLibraries, @Nullable Map<String, WatchedLongSparseArray<SharedLibraryInfo>> newLibraries)13029     private static SharedLibraryInfo getSharedLibraryInfo(String name, long version,
13030             Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingLibraries,
13031             @Nullable Map<String, WatchedLongSparseArray<SharedLibraryInfo>> newLibraries) {
13032         if (newLibraries != null) {
13033             final WatchedLongSparseArray<SharedLibraryInfo> versionedLib = newLibraries.get(name);
13034             SharedLibraryInfo info = null;
13035             if (versionedLib != null) {
13036                 info = versionedLib.get(version);
13037             }
13038             if (info != null) {
13039                 return info;
13040             }
13041         }
13042         final WatchedLongSparseArray<SharedLibraryInfo> versionedLib = existingLibraries.get(name);
13043         if (versionedLib == null) {
13044             return null;
13045         }
13046         return versionedLib.get(version);
13047     }
13048 
getLatestSharedLibraVersionLPr(AndroidPackage pkg)13049     private SharedLibraryInfo getLatestSharedLibraVersionLPr(AndroidPackage pkg) {
13050         WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(
13051                 pkg.getStaticSharedLibName());
13052         if (versionedLib == null) {
13053             return null;
13054         }
13055         long previousLibVersion = -1;
13056         final int versionCount = versionedLib.size();
13057         for (int i = 0; i < versionCount; i++) {
13058             final long libVersion = versionedLib.keyAt(i);
13059             if (libVersion < pkg.getStaticSharedLibVersion()) {
13060                 previousLibVersion = Math.max(previousLibVersion, libVersion);
13061             }
13062         }
13063         if (previousLibVersion >= 0) {
13064             return versionedLib.get(previousLibVersion);
13065         }
13066         return null;
13067     }
13068 
13069 
13070     @Nullable
getSharedLibLatestVersionSetting(@onNull ScanResult scanResult)13071     private PackageSetting getSharedLibLatestVersionSetting(@NonNull ScanResult scanResult) {
13072         PackageSetting sharedLibPackage = null;
13073         synchronized (mLock) {
13074             final SharedLibraryInfo latestSharedLibraVersionLPr =
13075                     getLatestSharedLibraVersionLPr(scanResult.request.parsedPackage);
13076             if (latestSharedLibraVersionLPr != null) {
13077                 sharedLibPackage = mSettings.getPackageLPr(
13078                         latestSharedLibraVersionLPr.getPackageName());
13079             }
13080         }
13081         return sharedLibPackage;
13082     }
13083 
shutdown()13084     public void shutdown() {
13085         mCompilerStats.writeNow();
13086         mDexManager.writePackageDexUsageNow();
13087         PackageWatchdog.getInstance(mContext).writeNow();
13088 
13089         synchronized (mLock) {
13090             mPackageUsage.writeNow(mSettings.getPackagesLocked());
13091 
13092             // This is the last chance to write out pending restriction settings
13093             if (mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
13094                 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
13095                 for (int userId : mDirtyUsers) {
13096                     mSettings.writePackageRestrictionsLPr(userId);
13097                 }
13098                 mDirtyUsers.clear();
13099             }
13100         }
13101     }
13102 
13103     @Override
dumpProfiles(String packageName)13104     public void dumpProfiles(String packageName) {
13105         /* Only the shell, root, or the app user should be able to dump profiles. */
13106         final int callingUid = Binder.getCallingUid();
13107         final String[] callerPackageNames = getPackagesForUid(callingUid);
13108         if (callingUid != Process.SHELL_UID
13109                 && callingUid != Process.ROOT_UID
13110                 && !ArrayUtils.contains(callerPackageNames, packageName)) {
13111             throw new SecurityException("dumpProfiles");
13112         }
13113 
13114         AndroidPackage pkg;
13115         synchronized (mLock) {
13116             pkg = mPackages.get(packageName);
13117             if (pkg == null) {
13118                 throw new IllegalArgumentException("Unknown package: " + packageName);
13119             }
13120         }
13121 
13122         synchronized (mInstallLock) {
13123             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
13124             mArtManagerService.dumpProfiles(pkg);
13125             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13126         }
13127     }
13128 
13129     @Override
forceDexOpt(String packageName)13130     public void forceDexOpt(String packageName) {
13131         enforceSystemOrRoot("forceDexOpt");
13132 
13133         AndroidPackage pkg;
13134         PackageSetting pkgSetting;
13135         synchronized (mLock) {
13136             pkg = mPackages.get(packageName);
13137             pkgSetting = mSettings.getPackageLPr(packageName);
13138             if (pkg == null || pkgSetting == null) {
13139                 throw new IllegalArgumentException("Unknown package: " + packageName);
13140             }
13141         }
13142 
13143         synchronized (mInstallLock) {
13144             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
13145 
13146             // Whoever is calling forceDexOpt wants a compiled package.
13147             // Don't use profiles since that may cause compilation to be skipped.
13148             final int res = performDexOptInternalWithDependenciesLI(pkg, pkgSetting,
13149                     new DexoptOptions(packageName,
13150                             getDefaultCompilerFilter(),
13151                             DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
13152 
13153             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13154             if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
13155                 throw new IllegalStateException("Failed to dexopt: " + res);
13156             }
13157         }
13158     }
13159 
13160     @GuardedBy("mLock")
verifyPackageUpdateLPr(PackageSetting oldPkg, AndroidPackage newPkg)13161     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, AndroidPackage newPkg) {
13162         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
13163             Slog.w(TAG, "Unable to update from " + oldPkg.name
13164                     + " to " + newPkg.getPackageName()
13165                     + ": old package not in system partition");
13166             return false;
13167         } else if (mPackages.get(oldPkg.name) != null) {
13168             Slog.w(TAG, "Unable to update from " + oldPkg.name
13169                     + " to " + newPkg.getPackageName()
13170                     + ": old package still exists");
13171             return false;
13172         }
13173         return true;
13174     }
13175 
13176     @GuardedBy("mInstallLock")
removeCodePathLI(File codePath)13177     void removeCodePathLI(File codePath) {
13178         if (codePath.isDirectory()) {
13179             final File codePathParent = codePath.getParentFile();
13180             final boolean needRemoveParent = codePathParent.getName().startsWith(RANDOM_DIR_PREFIX);
13181             try {
13182                 final boolean isIncremental = (mIncrementalManager != null && isIncrementalPath(
13183                         codePath.getAbsolutePath()));
13184                 if (isIncremental) {
13185                     if (needRemoveParent) {
13186                         mIncrementalManager.rmPackageDir(codePathParent);
13187                     } else {
13188                         mIncrementalManager.rmPackageDir(codePath);
13189                     }
13190                 }
13191 
13192                 mInstaller.rmPackageDir(codePath.getAbsolutePath());
13193                 if (needRemoveParent) {
13194                     mInstaller.rmPackageDir(codePathParent.getAbsolutePath());
13195                     removeCachedResult(codePathParent);
13196                 }
13197             } catch (InstallerException e) {
13198                 Slog.w(TAG, "Failed to remove code path", e);
13199             }
13200         } else {
13201             codePath.delete();
13202         }
13203     }
13204 
removeCachedResult(@onNull File codePath)13205     private void removeCachedResult(@NonNull File codePath) {
13206         if (mCacheDir == null) {
13207             return;
13208         }
13209 
13210         final PackageCacher cacher = new PackageCacher(mCacheDir);
13211         // Find and delete the cached result belong to the given codePath.
13212         cacher.cleanCachedResult(codePath);
13213     }
13214 
resolveUserIds(int userId)13215     private int[] resolveUserIds(int userId) {
13216         return (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds() : new int[] { userId };
13217     }
13218 
clearAppDataLIF(AndroidPackage pkg, int userId, int flags)13219     private void clearAppDataLIF(AndroidPackage pkg, int userId, int flags) {
13220         if (pkg == null) {
13221             return;
13222         }
13223         clearAppDataLeafLIF(pkg, userId, flags);
13224 
13225         if ((flags & Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES) == 0) {
13226             clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
13227         }
13228     }
13229 
clearAppDataLeafLIF(AndroidPackage pkg, int userId, int flags)13230     private void clearAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
13231         final PackageSetting ps;
13232         synchronized (mLock) {
13233             ps = mSettings.getPackageLPr(pkg.getPackageName());
13234         }
13235         for (int realUserId : resolveUserIds(userId)) {
13236             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
13237             try {
13238                 mInstaller.clearAppData(pkg.getVolumeUuid(), pkg.getPackageName(), realUserId,
13239                         flags, ceDataInode);
13240             } catch (InstallerException e) {
13241                 Slog.w(TAG, String.valueOf(e));
13242             }
13243         }
13244     }
13245 
destroyAppDataLIF(AndroidPackage pkg, int userId, int flags)13246     private void destroyAppDataLIF(AndroidPackage pkg, int userId, int flags) {
13247         if (pkg == null) {
13248             Slog.wtf(TAG, "Package was null!", new Throwable());
13249             return;
13250         }
13251         destroyAppDataLeafLIF(pkg, userId, flags);
13252     }
13253 
destroyAppDataLeafLIF(AndroidPackage pkg, int userId, int flags)13254     private void destroyAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
13255         final PackageSetting ps;
13256         synchronized (mLock) {
13257             ps = mSettings.getPackageLPr(pkg.getPackageName());
13258         }
13259         for (int realUserId : resolveUserIds(userId)) {
13260             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
13261             try {
13262                 mInstaller.destroyAppData(pkg.getVolumeUuid(), pkg.getPackageName(), realUserId,
13263                         flags, ceDataInode);
13264             } catch (InstallerException e) {
13265                 Slog.w(TAG, String.valueOf(e));
13266             }
13267             mDexManager.notifyPackageDataDestroyed(pkg.getPackageName(), userId);
13268         }
13269     }
13270 
destroyAppProfilesLIF(AndroidPackage pkg)13271     private void destroyAppProfilesLIF(AndroidPackage pkg) {
13272         if (pkg == null) {
13273             Slog.wtf(TAG, "Package was null!", new Throwable());
13274             return;
13275         }
13276         destroyAppProfilesLeafLIF(pkg);
13277     }
13278 
destroyAppProfilesLeafLIF(AndroidPackage pkg)13279     private void destroyAppProfilesLeafLIF(AndroidPackage pkg) {
13280         try {
13281             mInstaller.destroyAppProfiles(pkg.getPackageName());
13282         } catch (InstallerException e) {
13283             Slog.w(TAG, String.valueOf(e));
13284         }
13285     }
13286 
clearAppProfilesLIF(AndroidPackage pkg, int userId)13287     private void clearAppProfilesLIF(AndroidPackage pkg, int userId) {
13288         if (pkg == null) {
13289             Slog.wtf(TAG, "Package was null!", new Throwable());
13290             return;
13291         }
13292         mArtManagerService.clearAppProfiles(pkg);
13293     }
13294 
13295     @GuardedBy("mLock")
applyDefiningSharedLibraryUpdateLocked( AndroidPackage pkg, SharedLibraryInfo libInfo, BiConsumer<SharedLibraryInfo, SharedLibraryInfo> action)13296     private void applyDefiningSharedLibraryUpdateLocked(
13297             AndroidPackage pkg, SharedLibraryInfo libInfo,
13298             BiConsumer<SharedLibraryInfo, SharedLibraryInfo> action) {
13299         // Note that libraries defined by this package may be null if:
13300         // - Package manager was unable to create the shared library. The package still
13301         //   gets installed, but the shared library does not get created.
13302         // Or:
13303         // - Package manager is in a state where package isn't scanned yet. This will
13304         //   get called again after scanning to fix the dependencies.
13305         if (AndroidPackageUtils.isLibrary(pkg)) {
13306             if (pkg.getStaticSharedLibName() != null) {
13307                 SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr(
13308                         pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion());
13309                 if (definedLibrary != null) {
13310                     action.accept(definedLibrary, libInfo);
13311                 }
13312             } else {
13313                 for (String libraryName : pkg.getLibraryNames()) {
13314                     SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr(
13315                             libraryName, SharedLibraryInfo.VERSION_UNDEFINED);
13316                     if (definedLibrary != null) {
13317                         action.accept(definedLibrary, libInfo);
13318                     }
13319                 }
13320             }
13321         }
13322     }
13323 
13324     @GuardedBy("mLock")
addSharedLibraryLPr(AndroidPackage pkg, Set<String> usesLibraryFiles, SharedLibraryInfo libInfo, @Nullable AndroidPackage changingLib, @Nullable PackageSetting changingLibSetting)13325     private void addSharedLibraryLPr(AndroidPackage pkg, Set<String> usesLibraryFiles,
13326             SharedLibraryInfo libInfo, @Nullable AndroidPackage changingLib,
13327             @Nullable PackageSetting changingLibSetting) {
13328         if (libInfo.getPath() != null) {
13329             usesLibraryFiles.add(libInfo.getPath());
13330             return;
13331         }
13332         AndroidPackage pkgForCodePaths = mPackages.get(libInfo.getPackageName());
13333         PackageSetting pkgSetting = mSettings.getPackageLPr(libInfo.getPackageName());
13334         if (changingLib != null && changingLib.getPackageName().equals(libInfo.getPackageName())) {
13335             // If we are doing this while in the middle of updating a library apk,
13336             // then we need to make sure to use that new apk for determining the
13337             // dependencies here.  (We haven't yet finished committing the new apk
13338             // to the package manager state.)
13339             if (pkgForCodePaths == null
13340                     || pkgForCodePaths.getPackageName().equals(changingLib.getPackageName())) {
13341                 pkgForCodePaths = changingLib;
13342                 pkgSetting = changingLibSetting;
13343             }
13344         }
13345         if (pkgForCodePaths != null) {
13346             usesLibraryFiles.addAll(AndroidPackageUtils.getAllCodePaths(pkgForCodePaths));
13347             // If the package provides libraries, add the dependency to them.
13348             applyDefiningSharedLibraryUpdateLocked(pkg, libInfo, SharedLibraryInfo::addDependency);
13349             if (pkgSetting != null) {
13350                 usesLibraryFiles.addAll(pkgSetting.getPkgState().getUsesLibraryFiles());
13351             }
13352         }
13353     }
13354 
13355     @GuardedBy("mLock")
updateSharedLibrariesLocked(AndroidPackage pkg, PackageSetting pkgSetting, @Nullable AndroidPackage changingLib, @Nullable PackageSetting changingLibSetting, Map<String, AndroidPackage> availablePackages)13356     private void updateSharedLibrariesLocked(AndroidPackage pkg, PackageSetting pkgSetting,
13357             @Nullable AndroidPackage changingLib, @Nullable PackageSetting changingLibSetting,
13358             Map<String, AndroidPackage> availablePackages)
13359             throws PackageManagerException {
13360         final ArrayList<SharedLibraryInfo> sharedLibraryInfos = collectSharedLibraryInfos(
13361                 pkgSetting.pkg, availablePackages, mSharedLibraries, null /* newLibraries */,
13362                 mInjector.getCompatibility());
13363         executeSharedLibrariesUpdateLPr(pkg, pkgSetting, changingLib, changingLibSetting,
13364                 sharedLibraryInfos, mUserManager.getUserIds());
13365     }
13366 
collectSharedLibraryInfos(AndroidPackage pkg, Map<String, AndroidPackage> availablePackages, @NonNull final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingLibraries, @Nullable final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> newLibraries, PlatformCompat platformCompat)13367     private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(AndroidPackage pkg,
13368             Map<String, AndroidPackage> availablePackages,
13369             @NonNull final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingLibraries,
13370             @Nullable final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> newLibraries,
13371             PlatformCompat platformCompat) throws PackageManagerException {
13372         if (pkg == null) {
13373             return null;
13374         }
13375         // The collection used here must maintain the order of addition (so
13376         // that libraries are searched in the correct order) and must have no
13377         // duplicates.
13378         ArrayList<SharedLibraryInfo> usesLibraryInfos = null;
13379         if (!pkg.getUsesLibraries().isEmpty()) {
13380             usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesLibraries(), null, null,
13381                     pkg.getPackageName(), true, pkg.getTargetSdkVersion(), null,
13382                     availablePackages, existingLibraries, newLibraries);
13383         }
13384         if (!pkg.getUsesStaticLibraries().isEmpty()) {
13385             usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesStaticLibraries(),
13386                     pkg.getUsesStaticLibrariesVersions(), pkg.getUsesStaticLibrariesCertDigests(),
13387                     pkg.getPackageName(), true, pkg.getTargetSdkVersion(), usesLibraryInfos,
13388                     availablePackages, existingLibraries, newLibraries);
13389         }
13390         if (!pkg.getUsesOptionalLibraries().isEmpty()) {
13391             usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesOptionalLibraries(),
13392                     null, null, pkg.getPackageName(), false, pkg.getTargetSdkVersion(),
13393                     usesLibraryInfos, availablePackages, existingLibraries, newLibraries);
13394         }
13395         if (platformCompat.isChangeEnabledInternal(ENFORCE_NATIVE_SHARED_LIBRARY_DEPENDENCIES,
13396                 pkg.getPackageName(), pkg.getTargetSdkVersion())) {
13397             if (!pkg.getUsesNativeLibraries().isEmpty()) {
13398                 usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesNativeLibraries(), null,
13399                         null, pkg.getPackageName(), true, pkg.getTargetSdkVersion(),
13400                         usesLibraryInfos, availablePackages, existingLibraries, newLibraries);
13401             }
13402             if (!pkg.getUsesOptionalNativeLibraries().isEmpty()) {
13403                 usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesOptionalNativeLibraries(),
13404                         null, null, pkg.getPackageName(), false, pkg.getTargetSdkVersion(),
13405                         usesLibraryInfos, availablePackages, existingLibraries, newLibraries);
13406             }
13407         }
13408         return usesLibraryInfos;
13409     }
13410 
executeSharedLibrariesUpdateLPr(AndroidPackage pkg, @NonNull PackageSetting pkgSetting, @Nullable AndroidPackage changingLib, @Nullable PackageSetting changingLibSetting, ArrayList<SharedLibraryInfo> usesLibraryInfos, int[] allUsers)13411     private void executeSharedLibrariesUpdateLPr(AndroidPackage pkg,
13412             @NonNull PackageSetting pkgSetting, @Nullable AndroidPackage changingLib,
13413             @Nullable PackageSetting changingLibSetting,
13414             ArrayList<SharedLibraryInfo> usesLibraryInfos, int[] allUsers) {
13415         // If the package provides libraries, clear their old dependencies.
13416         // This method will set them up again.
13417         applyDefiningSharedLibraryUpdateLocked(pkg, null, (definingLibrary, dependency) -> {
13418             definingLibrary.clearDependencies();
13419         });
13420         if (usesLibraryInfos != null) {
13421             pkgSetting.getPkgState().setUsesLibraryInfos(usesLibraryInfos);
13422             // Use LinkedHashSet to preserve the order of files added to
13423             // usesLibraryFiles while eliminating duplicates.
13424             Set<String> usesLibraryFiles = new LinkedHashSet<>();
13425             for (SharedLibraryInfo libInfo : usesLibraryInfos) {
13426                 addSharedLibraryLPr(pkg, usesLibraryFiles, libInfo, changingLib,
13427                         changingLibSetting);
13428             }
13429             pkgSetting.getPkgState().setUsesLibraryFiles(new ArrayList<>(usesLibraryFiles));
13430             // let's make sure we mark all static shared libraries as installed for the same users
13431             // that its dependent packages are installed for.
13432             int[] installedUsers = new int[allUsers.length];
13433             int installedUserCount = 0;
13434             for (int u = 0; u < allUsers.length; u++) {
13435                 if (pkgSetting.getInstalled(allUsers[u])) {
13436                     installedUsers[installedUserCount++] = allUsers[u];
13437                 }
13438             }
13439             for (SharedLibraryInfo sharedLibraryInfo : usesLibraryInfos) {
13440                 if (!sharedLibraryInfo.isStatic()) {
13441                     continue;
13442                 }
13443                 final PackageSetting staticLibPkgSetting =
13444                         getPackageSetting(sharedLibraryInfo.getPackageName());
13445                 if (staticLibPkgSetting == null) {
13446                     Slog.wtf(TAG, "Shared lib without setting: " + sharedLibraryInfo);
13447                     continue;
13448                 }
13449                 for (int u = 0; u < installedUserCount; u++) {
13450                     staticLibPkgSetting.setInstalled(true, installedUsers[u]);
13451                 }
13452             }
13453         } else {
13454             pkgSetting.getPkgState().setUsesLibraryInfos(Collections.emptyList())
13455                     .setUsesLibraryFiles(Collections.emptyList());
13456         }
13457     }
13458 
13459     @GuardedBy("mLock")
collectSharedLibraryInfos( @onNull List<String> requestedLibraries, @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests, @NonNull String packageName, boolean required, int targetSdk, @Nullable ArrayList<SharedLibraryInfo> outUsedLibraries, @NonNull final Map<String, AndroidPackage> availablePackages, @NonNull final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingLibraries, @Nullable final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> newLibraries)13460     private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(
13461             @NonNull List<String> requestedLibraries,
13462             @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
13463             @NonNull String packageName, boolean required, int targetSdk,
13464             @Nullable ArrayList<SharedLibraryInfo> outUsedLibraries,
13465             @NonNull final Map<String, AndroidPackage> availablePackages,
13466             @NonNull final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingLibraries,
13467             @Nullable final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> newLibraries)
13468             throws PackageManagerException {
13469         final int libCount = requestedLibraries.size();
13470         for (int i = 0; i < libCount; i++) {
13471             final String libName = requestedLibraries.get(i);
13472             final long libVersion = requiredVersions != null ? requiredVersions[i]
13473                     : SharedLibraryInfo.VERSION_UNDEFINED;
13474             final SharedLibraryInfo libraryInfo = getSharedLibraryInfo(libName, libVersion,
13475                     existingLibraries, newLibraries);
13476             if (libraryInfo == null) {
13477                 if (required) {
13478                     throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
13479                             "Package " + packageName + " requires unavailable shared library "
13480                                     + libName + "; failing!");
13481                 } else if (DEBUG_SHARED_LIBRARIES) {
13482                     Slog.i(TAG, "Package " + packageName
13483                             + " desires unavailable shared library "
13484                             + libName + "; ignoring!");
13485                 }
13486             } else {
13487                 if (requiredVersions != null && requiredCertDigests != null) {
13488                     if (libraryInfo.getLongVersion() != requiredVersions[i]) {
13489                         throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
13490                             "Package " + packageName + " requires unavailable static shared"
13491                                     + " library " + libName + " version "
13492                                     + libraryInfo.getLongVersion() + "; failing!");
13493                     }
13494                     AndroidPackage pkg = availablePackages.get(libraryInfo.getPackageName());
13495                     SigningDetails libPkg = pkg == null ? null : pkg.getSigningDetails();
13496                     if (libPkg == null) {
13497                         throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
13498                                 "Package " + packageName + " requires unavailable static shared"
13499                                         + " library; failing!");
13500                     }
13501                     final String[] expectedCertDigests = requiredCertDigests[i];
13502                     if (expectedCertDigests.length > 1) {
13503                         // For apps targeting O MR1 we require explicit enumeration of all certs.
13504                         final String[] libCertDigests = (targetSdk >= Build.VERSION_CODES.O_MR1)
13505                                 ? PackageUtils.computeSignaturesSha256Digests(
13506                                 libPkg.signatures)
13507                                 : PackageUtils.computeSignaturesSha256Digests(
13508                                         new Signature[]{libPkg.signatures[0]});
13509 
13510                         // Take a shortcut if sizes don't match. Note that if an app doesn't
13511                         // target O we don't parse the "additional-certificate" tags similarly
13512                         // how we only consider all certs only for apps targeting O (see above).
13513                         // Therefore, the size check is safe to make.
13514                         if (expectedCertDigests.length != libCertDigests.length) {
13515                             throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
13516                                     "Package " + packageName + " requires differently signed" +
13517                                             " static shared library; failing!");
13518                         }
13519 
13520                         // Use a predictable order as signature order may vary
13521                         Arrays.sort(libCertDigests);
13522                         Arrays.sort(expectedCertDigests);
13523 
13524                         final int certCount = libCertDigests.length;
13525                         for (int j = 0; j < certCount; j++) {
13526                             if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
13527                                 throw new PackageManagerException(
13528                                         INSTALL_FAILED_MISSING_SHARED_LIBRARY,
13529                                         "Package " + packageName + " requires differently signed" +
13530                                                 " static shared library; failing!");
13531                             }
13532                         }
13533                     } else {
13534                         // lib signing cert could have rotated beyond the one expected, check to see
13535                         // if the new one has been blessed by the old
13536                         byte[] digestBytes = HexEncoding.decode(
13537                                 expectedCertDigests[0], false /* allowSingleChar */);
13538                         if (!libPkg.hasSha256Certificate(digestBytes)) {
13539                             throw new PackageManagerException(
13540                                     INSTALL_FAILED_MISSING_SHARED_LIBRARY,
13541                                     "Package " + packageName + " requires differently signed" +
13542                                             " static shared library; failing!");
13543                         }
13544                     }
13545                 }
13546                 if (outUsedLibraries == null) {
13547                     outUsedLibraries = new ArrayList<>();
13548                 }
13549                 outUsedLibraries.add(libraryInfo);
13550             }
13551         }
13552         return outUsedLibraries;
13553     }
13554 
hasString(List<String> list, List<String> which)13555     private static boolean hasString(List<String> list, List<String> which) {
13556         if (list == null || which == null) {
13557             return false;
13558         }
13559         for (int i=list.size()-1; i>=0; i--) {
13560             for (int j=which.size()-1; j>=0; j--) {
13561                 if (which.get(j).equals(list.get(i))) {
13562                     return true;
13563                 }
13564             }
13565         }
13566         return false;
13567     }
13568 
13569     @GuardedBy("mLock")
updateAllSharedLibrariesLocked( @ullable AndroidPackage updatedPkg, @Nullable PackageSetting updatedPkgSetting, Map<String, AndroidPackage> availablePackages)13570     private ArrayList<AndroidPackage> updateAllSharedLibrariesLocked(
13571             @Nullable AndroidPackage updatedPkg, @Nullable PackageSetting updatedPkgSetting,
13572             Map<String, AndroidPackage> availablePackages) {
13573         ArrayList<AndroidPackage> resultList = null;
13574         // Set of all descendants of a library; used to eliminate cycles
13575         ArraySet<String> descendants = null;
13576         // The current list of packages that need updating
13577         List<Pair<AndroidPackage, PackageSetting>> needsUpdating = null;
13578         if (updatedPkg != null && updatedPkgSetting != null) {
13579             needsUpdating = new ArrayList<>(1);
13580             needsUpdating.add(Pair.create(updatedPkg, updatedPkgSetting));
13581         }
13582         do {
13583             final Pair<AndroidPackage, PackageSetting> changingPkgPair =
13584                     (needsUpdating == null) ? null : needsUpdating.remove(0);
13585             final AndroidPackage changingPkg = changingPkgPair != null
13586                     ? changingPkgPair.first : null;
13587             final PackageSetting changingPkgSetting = changingPkgPair != null
13588                     ? changingPkgPair.second : null;
13589             for (int i = mPackages.size() - 1; i >= 0; --i) {
13590                 final AndroidPackage pkg = mPackages.valueAt(i);
13591                 final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.getPackageName());
13592                 if (changingPkg != null
13593                         && !hasString(pkg.getUsesLibraries(), changingPkg.getLibraryNames())
13594                         && !hasString(pkg.getUsesOptionalLibraries(), changingPkg.getLibraryNames())
13595                         && !ArrayUtils.contains(pkg.getUsesStaticLibraries(),
13596                         changingPkg.getStaticSharedLibName())) {
13597                     continue;
13598                 }
13599                 if (resultList == null) {
13600                     resultList = new ArrayList<>();
13601                 }
13602                 resultList.add(pkg);
13603                 // if we're updating a shared library, all of its descendants must be updated
13604                 if (changingPkg != null) {
13605                     if (descendants == null) {
13606                         descendants = new ArraySet<>();
13607                     }
13608                     if (!descendants.contains(pkg.getPackageName())) {
13609                         descendants.add(pkg.getPackageName());
13610                         needsUpdating.add(Pair.create(pkg, pkgSetting));
13611                     }
13612                 }
13613                 try {
13614                     updateSharedLibrariesLocked(pkg, pkgSetting, changingPkg,
13615                             changingPkgSetting, availablePackages);
13616                 } catch (PackageManagerException e) {
13617                     // If a system app update or an app and a required lib missing we
13618                     // delete the package and for updated system apps keep the data as
13619                     // it is better for the user to reinstall than to be in an limbo
13620                     // state. Also libs disappearing under an app should never happen
13621                     // - just in case.
13622                     if (!pkg.isSystem() || pkgSetting.getPkgState().isUpdatedSystemApp()) {
13623                         final int flags = pkgSetting.getPkgState().isUpdatedSystemApp()
13624                                 ? PackageManager.DELETE_KEEP_DATA : 0;
13625                         deletePackageLIF(pkg.getPackageName(), null, true,
13626                                 mUserManager.getUserIds(), flags, null,
13627                                 true, null);
13628                     }
13629                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
13630                 }
13631             }
13632         } while (needsUpdating != null && needsUpdating.size() > 0);
13633         return resultList;
13634     }
13635 
getVendorPartitionVersion()13636     private int getVendorPartitionVersion() {
13637         final String version = SystemProperties.get("ro.vndk.version");
13638         if (!version.isEmpty()) {
13639             try {
13640                 return Integer.parseInt(version);
13641             } catch (NumberFormatException ignore) {
13642                 if (ArrayUtils.contains(Build.VERSION.ACTIVE_CODENAMES, version)) {
13643                     return Build.VERSION_CODES.CUR_DEVELOPMENT;
13644                 }
13645             }
13646         }
13647         return Build.VERSION_CODES.P;
13648     }
13649 
13650     @GuardedBy({"mInstallLock", "mLock"})
scanPackageTracedLI(ParsedPackage parsedPackage, final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime, @Nullable UserHandle user, String cpuAbiOverride)13651     private ScanResult scanPackageTracedLI(ParsedPackage parsedPackage,
13652             final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
13653             @Nullable UserHandle user, String cpuAbiOverride) throws PackageManagerException {
13654         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
13655         try {
13656             return scanPackageNewLI(parsedPackage, parseFlags, scanFlags, currentTime, user,
13657                     cpuAbiOverride);
13658         } finally {
13659             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13660         }
13661     }
13662 
13663     /** The result of a package scan. */
13664     @VisibleForTesting
13665     static class ScanResult {
13666         /** The request that initiated the scan that produced this result. */
13667         public final ScanRequest request;
13668         /** Whether or not the package scan was successful */
13669         public final boolean success;
13670         /**
13671          * Whether or not the original PackageSetting needs to be updated with this result on
13672          * commit.
13673          */
13674         public final boolean existingSettingCopied;
13675         /**
13676          * The final package settings. This may be the same object passed in
13677          * the {@link ScanRequest}, but, with modified values.
13678          */
13679         @Nullable public final PackageSetting pkgSetting;
13680         /** ABI code paths that have changed in the package scan */
13681         @Nullable public final List<String> changedAbiCodePath;
13682 
13683         public final SharedLibraryInfo staticSharedLibraryInfo;
13684 
13685         public final List<SharedLibraryInfo> dynamicSharedLibraryInfos;
13686 
ScanResult( ScanRequest request, boolean success, @Nullable PackageSetting pkgSetting, @Nullable List<String> changedAbiCodePath, boolean existingSettingCopied, SharedLibraryInfo staticSharedLibraryInfo, List<SharedLibraryInfo> dynamicSharedLibraryInfos)13687         public ScanResult(
13688                 ScanRequest request, boolean success,
13689                 @Nullable PackageSetting pkgSetting,
13690                 @Nullable List<String> changedAbiCodePath, boolean existingSettingCopied,
13691                 SharedLibraryInfo staticSharedLibraryInfo,
13692                 List<SharedLibraryInfo> dynamicSharedLibraryInfos) {
13693             this.request = request;
13694             this.success = success;
13695             this.pkgSetting = pkgSetting;
13696             this.changedAbiCodePath = changedAbiCodePath;
13697             this.existingSettingCopied = existingSettingCopied;
13698             this.staticSharedLibraryInfo = staticSharedLibraryInfo;
13699             this.dynamicSharedLibraryInfos = dynamicSharedLibraryInfos;
13700         }
13701     }
13702 
13703     /** A package to be scanned */
13704     @VisibleForTesting
13705     static class ScanRequest {
13706         /** The parsed package */
13707         @NonNull public final ParsedPackage parsedPackage;
13708         /** The package this package replaces */
13709         @Nullable public final AndroidPackage oldPkg;
13710         /** Shared user settings, if the package has a shared user */
13711         @Nullable public final SharedUserSetting sharedUserSetting;
13712         /**
13713          * Package settings of the currently installed version.
13714          * <p><em>IMPORTANT:</em> The contents of this object may be modified
13715          * during scan.
13716          */
13717         @Nullable public final PackageSetting pkgSetting;
13718         /** A copy of the settings for the currently installed version */
13719         @Nullable public final PackageSetting oldPkgSetting;
13720         /** Package settings for the disabled version on the /system partition */
13721         @Nullable public final PackageSetting disabledPkgSetting;
13722         /** Package settings for the installed version under its original package name */
13723         @Nullable public final PackageSetting originalPkgSetting;
13724         /** The real package name of a renamed application */
13725         @Nullable public final String realPkgName;
13726         public final @ParseFlags int parseFlags;
13727         public final @ScanFlags int scanFlags;
13728         /** The user for which the package is being scanned */
13729         @Nullable public final UserHandle user;
13730         /** Whether or not the platform package is being scanned */
13731         public final boolean isPlatformPackage;
13732         /** Override value for package ABI if set during install */
13733         @Nullable
13734         public final String cpuAbiOverride;
ScanRequest( @onNull ParsedPackage parsedPackage, @Nullable SharedUserSetting sharedUserSetting, @Nullable AndroidPackage oldPkg, @Nullable PackageSetting pkgSetting, @Nullable PackageSetting disabledPkgSetting, @Nullable PackageSetting originalPkgSetting, @Nullable String realPkgName, @ParseFlags int parseFlags, @ScanFlags int scanFlags, boolean isPlatformPackage, @Nullable UserHandle user, @Nullable String cpuAbiOverride)13735         public ScanRequest(
13736                 @NonNull ParsedPackage parsedPackage,
13737                 @Nullable SharedUserSetting sharedUserSetting,
13738                 @Nullable AndroidPackage oldPkg,
13739                 @Nullable PackageSetting pkgSetting,
13740                 @Nullable PackageSetting disabledPkgSetting,
13741                 @Nullable PackageSetting originalPkgSetting,
13742                 @Nullable String realPkgName,
13743                 @ParseFlags int parseFlags,
13744                 @ScanFlags int scanFlags,
13745                 boolean isPlatformPackage,
13746                 @Nullable UserHandle user,
13747                 @Nullable String cpuAbiOverride) {
13748             this.parsedPackage = parsedPackage;
13749             this.oldPkg = oldPkg;
13750             this.pkgSetting = pkgSetting;
13751             this.sharedUserSetting = sharedUserSetting;
13752             this.oldPkgSetting = pkgSetting == null ? null : new PackageSetting(pkgSetting);
13753             this.disabledPkgSetting = disabledPkgSetting;
13754             this.originalPkgSetting = originalPkgSetting;
13755             this.realPkgName = realPkgName;
13756             this.parseFlags = parseFlags;
13757             this.scanFlags = scanFlags;
13758             this.isPlatformPackage = isPlatformPackage;
13759             this.user = user;
13760             this.cpuAbiOverride = cpuAbiOverride;
13761         }
13762     }
13763 
13764     /**
13765      * Returns the actual scan flags depending upon the state of the other settings.
13766      * <p>Updated system applications will not have the following flags set
13767      * by default and need to be adjusted after the fact:
13768      * <ul>
13769      * <li>{@link #SCAN_AS_SYSTEM}</li>
13770      * <li>{@link #SCAN_AS_PRIVILEGED}</li>
13771      * <li>{@link #SCAN_AS_OEM}</li>
13772      * <li>{@link #SCAN_AS_VENDOR}</li>
13773      * <li>{@link #SCAN_AS_PRODUCT}</li>
13774      * <li>{@link #SCAN_AS_SYSTEM_EXT}</li>
13775      * <li>{@link #SCAN_AS_INSTANT_APP}</li>
13776      * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
13777      * <li>{@link #SCAN_AS_ODM}</li>
13778      * </ul>
13779      */
adjustScanFlags(@canFlags int scanFlags, PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user, AndroidPackage pkg)13780     private @ScanFlags int adjustScanFlags(@ScanFlags int scanFlags,
13781             PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user,
13782             AndroidPackage pkg) {
13783 
13784         // TODO(patb): Do away entirely with disabledPkgSetting here. PkgSetting will always contain
13785         // the correct isSystem value now that we don't disable system packages before scan.
13786         final PackageSetting systemPkgSetting =
13787                 (scanFlags & SCAN_NEW_INSTALL) != 0 && disabledPkgSetting == null
13788                         && pkgSetting != null && pkgSetting.isSystem()
13789                         ? pkgSetting
13790                         : disabledPkgSetting;
13791         if (systemPkgSetting != null)  {
13792             // updated system application, must at least have SCAN_AS_SYSTEM
13793             scanFlags |= SCAN_AS_SYSTEM;
13794             if ((systemPkgSetting.pkgPrivateFlags
13795                     & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
13796                 scanFlags |= SCAN_AS_PRIVILEGED;
13797             }
13798             if ((systemPkgSetting.pkgPrivateFlags
13799                     & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
13800                 scanFlags |= SCAN_AS_OEM;
13801             }
13802             if ((systemPkgSetting.pkgPrivateFlags
13803                     & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
13804                 scanFlags |= SCAN_AS_VENDOR;
13805             }
13806             if ((systemPkgSetting.pkgPrivateFlags
13807                     & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0) {
13808                 scanFlags |= SCAN_AS_PRODUCT;
13809             }
13810             if ((systemPkgSetting.pkgPrivateFlags
13811                     & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0) {
13812                 scanFlags |= SCAN_AS_SYSTEM_EXT;
13813             }
13814             if ((systemPkgSetting.pkgPrivateFlags
13815                     & ApplicationInfo.PRIVATE_FLAG_ODM) != 0) {
13816                 scanFlags |= SCAN_AS_ODM;
13817             }
13818         }
13819         if (pkgSetting != null) {
13820             final int userId = ((user == null) ? 0 : user.getIdentifier());
13821             if (pkgSetting.getInstantApp(userId)) {
13822                 scanFlags |= SCAN_AS_INSTANT_APP;
13823             }
13824             if (pkgSetting.getVirtulalPreload(userId)) {
13825                 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
13826             }
13827         }
13828 
13829         // Scan as privileged apps that share a user with a priv-app.
13830         final boolean skipVendorPrivilegeScan = ((scanFlags & SCAN_AS_VENDOR) != 0)
13831                 && getVendorPartitionVersion() < 28;
13832         if (((scanFlags & SCAN_AS_PRIVILEGED) == 0)
13833                 && !pkg.isPrivileged()
13834                 && (pkg.getSharedUserId() != null)
13835                 && !skipVendorPrivilegeScan) {
13836             SharedUserSetting sharedUserSetting = null;
13837             try {
13838                 sharedUserSetting = mSettings.getSharedUserLPw(pkg.getSharedUserId(), 0,
13839                         0, false);
13840             } catch (PackageManagerException ignore) {
13841             }
13842             if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
13843                 // Exempt SharedUsers signed with the platform key.
13844                 // TODO(b/72378145) Fix this exemption. Force signature apps
13845                 // to allowlist their privileged permissions just like other
13846                 // priv-apps.
13847                 synchronized (mLock) {
13848                     PackageSetting platformPkgSetting = mSettings.getPackageLPr("android");
13849                     if ((compareSignatures(platformPkgSetting.signatures.mSigningDetails.signatures,
13850                             pkg.getSigningDetails().signatures)
13851                             != PackageManager.SIGNATURE_MATCH)) {
13852                         scanFlags |= SCAN_AS_PRIVILEGED;
13853                     }
13854                 }
13855             }
13856         }
13857 
13858         return scanFlags;
13859     }
13860 
13861     // TODO: scanPackageNewLI() and scanPackageOnly() should be merged. But, first, commiting
13862     // the results / removing app data needs to be moved up a level to the callers of this
13863     // method. Also, we need to solve the problem of potentially creating a new shared user
13864     // setting. That can probably be done later and patch things up after the fact.
13865     @GuardedBy({"mInstallLock", "mLock"})
13866     private ScanResult scanPackageNewLI(@NonNull ParsedPackage parsedPackage,
13867             final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
13868             @Nullable UserHandle user, String cpuAbiOverride) throws PackageManagerException {
13869 
13870         final String renamedPkgName = mSettings.getRenamedPackageLPr(
13871                 parsedPackage.getRealPackage());
13872         final String realPkgName = getRealPackageName(parsedPackage, renamedPkgName);
13873         if (realPkgName != null) {
13874             ensurePackageRenamed(parsedPackage, renamedPkgName);
13875         }
13876         final PackageSetting originalPkgSetting = getOriginalPackageLocked(parsedPackage,
13877                 renamedPkgName);
13878         final PackageSetting pkgSetting = mSettings.getPackageLPr(parsedPackage.getPackageName());
13879         final PackageSetting disabledPkgSetting =
13880                 mSettings.getDisabledSystemPkgLPr(parsedPackage.getPackageName());
13881 
13882         if (mTransferredPackages.contains(parsedPackage.getPackageName())) {
13883             Slog.w(TAG, "Package " + parsedPackage.getPackageName()
13884                     + " was transferred to another, but its .apk remains");
13885         }
13886 
13887         scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, parsedPackage);
13888         synchronized (mLock) {
13889             boolean isUpdatedSystemApp;
13890             if (pkgSetting != null) {
13891                 isUpdatedSystemApp = pkgSetting.getPkgState().isUpdatedSystemApp();
13892             } else {
13893                 isUpdatedSystemApp = disabledPkgSetting != null;
13894             }
13895             applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, isUpdatedSystemApp);
13896             assertPackageIsValid(parsedPackage, parseFlags, scanFlags);
13897 
13898             SharedUserSetting sharedUserSetting = null;
13899             if (parsedPackage.getSharedUserId() != null) {
13900                 // SIDE EFFECTS; may potentially allocate a new shared user
13901                 sharedUserSetting = mSettings.getSharedUserLPw(parsedPackage.getSharedUserId(),
13902                         0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
13903                 if (DEBUG_PACKAGE_SCANNING) {
13904                     if ((parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0) {
13905                         Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId()
13906                                 + " (uid=" + sharedUserSetting.userId + "):"
13907                                 + " packages=" + sharedUserSetting.packages);
13908                     }
13909                 }
13910             }
13911             String platformPackageName = mPlatformPackage == null
13912                     ? null : mPlatformPackage.getPackageName();
13913             final ScanRequest request = new ScanRequest(parsedPackage, sharedUserSetting,
13914                     pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting,
13915                     originalPkgSetting, realPkgName, parseFlags, scanFlags,
13916                     Objects.equals(parsedPackage.getPackageName(), platformPackageName), user,
13917                     cpuAbiOverride);
13918             return scanPackageOnlyLI(request, mInjector, mFactoryTest, currentTime);
13919         }
13920     }
13921 
13922 
13923     /**
13924      * Prepares the system to commit a {@link ScanResult} in a way that will not fail by registering
13925      * the app ID required for reconcile.
13926      * @return {@code true} if a new app ID was registered and will need to be cleaned up on
13927      *         failure.
13928      */
13929     private boolean optimisticallyRegisterAppId(@NonNull ScanResult result)
13930             throws PackageManagerException {
13931         if (!result.existingSettingCopied) {
13932             // THROWS: when we can't allocate a user id. add call to check if there's
13933             // enough space to ensure we won't throw; otherwise, don't modify state
13934             return mSettings.registerAppIdLPw(result.pkgSetting);
13935         }
13936         return false;
13937     }
13938 
13939     /**
13940      * Reverts any app ID creation that were made by
13941      * {@link #optimisticallyRegisterAppId(ScanResult)}. Note: this is only necessary if the
13942      * referenced method returned true.
13943      */
13944     private void cleanUpAppIdCreation(@NonNull ScanResult result) {
13945         // iff we've acquired an app ID for a new package setting, remove it so that it can be
13946         // acquired by another request.
13947         if (result.pkgSetting.appId > 0) {
13948             mSettings.removeAppIdLPw(result.pkgSetting.appId);
13949         }
13950     }
13951 
13952     /**
13953      * Commits the package scan and modifies system state.
13954      * <p><em>WARNING:</em> The method may throw an excpetion in the middle
13955      * of committing the package, leaving the system in an inconsistent state.
13956      * This needs to be fixed so, once we get to this point, no errors are
13957      * possible and the system is not left in an inconsistent state.
13958      */
13959     @GuardedBy({"mLock", "mInstallLock"})
13960     private AndroidPackage commitReconciledScanResultLocked(
13961             @NonNull ReconciledPackage reconciledPkg, int[] allUsers) {
13962         final ScanResult result = reconciledPkg.scanResult;
13963         final ScanRequest request = result.request;
13964         // TODO(b/135203078): Move this even further away
13965         ParsedPackage parsedPackage = request.parsedPackage;
13966         if ("android".equals(parsedPackage.getPackageName())) {
13967             // TODO(b/135203078): Move this to initial parse
13968             parsedPackage.setVersionCode(mSdkVersion)
13969                     .setVersionCodeMajor(0);
13970         }
13971 
13972         final AndroidPackage oldPkg = request.oldPkg;
13973         final @ParseFlags int parseFlags = request.parseFlags;
13974         final @ScanFlags int scanFlags = request.scanFlags;
13975         final PackageSetting oldPkgSetting = request.oldPkgSetting;
13976         final PackageSetting originalPkgSetting = request.originalPkgSetting;
13977         final UserHandle user = request.user;
13978         final String realPkgName = request.realPkgName;
13979         final List<String> changedAbiCodePath = result.changedAbiCodePath;
13980         final PackageSetting pkgSetting;
13981         if (request.pkgSetting != null && request.pkgSetting.sharedUser != null
13982                 && request.pkgSetting.sharedUser != result.pkgSetting.sharedUser) {
13983             // shared user changed, remove from old shared user
13984             request.pkgSetting.sharedUser.removePackage(request.pkgSetting);
13985         }
13986         if (result.existingSettingCopied) {
13987             pkgSetting = request.pkgSetting;
13988             pkgSetting.updateFrom(result.pkgSetting);
13989         } else {
13990             pkgSetting = result.pkgSetting;
13991             if (originalPkgSetting != null) {
13992                 mSettings.addRenamedPackageLPw(parsedPackage.getRealPackage(),
13993                         originalPkgSetting.name);
13994                 mTransferredPackages.add(originalPkgSetting.name);
13995             } else {
13996                 mSettings.removeRenamedPackageLPw(parsedPackage.getPackageName());
13997             }
13998         }
13999         if (pkgSetting.sharedUser != null) {
14000             pkgSetting.sharedUser.addPackage(pkgSetting);
14001         }
14002         if (reconciledPkg.installArgs != null && reconciledPkg.installArgs.forceQueryableOverride) {
14003             pkgSetting.forceQueryableOverride = true;
14004         }
14005 
14006         // If this is part of a standard install, set the initiating package name, else rely on
14007         // previous device state.
14008         if (reconciledPkg.installArgs != null) {
14009             InstallSource installSource = reconciledPkg.installArgs.installSource;
14010             if (installSource.initiatingPackageName != null) {
14011                 final PackageSetting ips = mSettings.getPackageLPr(
14012                         installSource.initiatingPackageName);
14013                 if (ips != null) {
14014                     installSource = installSource.setInitiatingPackageSignatures(
14015                             ips.signatures);
14016                 }
14017             }
14018             pkgSetting.setInstallSource(installSource);
14019         }
14020 
14021         // TODO(toddke): Consider a method specifically for modifying the Package object
14022         // post scan; or, moving this stuff out of the Package object since it has nothing
14023         // to do with the package on disk.
14024         // We need to have this here because addUserToSettingLPw() is sometimes responsible
14025         // for creating the application ID. If we did this earlier, we would be saving the
14026         // correct ID.
14027         parsedPackage.setUid(pkgSetting.appId);
14028         final AndroidPackage pkg = parsedPackage.hideAsFinal();
14029 
14030         mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
14031 
14032         if (realPkgName != null) {
14033             mTransferredPackages.add(pkg.getPackageName());
14034         }
14035 
14036         if (reconciledPkg.collectedSharedLibraryInfos != null) {
14037             executeSharedLibrariesUpdateLPr(pkg, pkgSetting, null, null,
14038                     reconciledPkg.collectedSharedLibraryInfos, allUsers);
14039         }
14040 
14041         final KeySetManagerService ksms = mSettings.getKeySetManagerService();
14042         if (reconciledPkg.removeAppKeySetData) {
14043             ksms.removeAppKeySetDataLPw(pkg.getPackageName());
14044         }
14045         if (reconciledPkg.sharedUserSignaturesChanged) {
14046             pkgSetting.sharedUser.signaturesChanged = Boolean.TRUE;
14047             pkgSetting.sharedUser.signatures.mSigningDetails = reconciledPkg.signingDetails;
14048         }
14049         pkgSetting.signatures.mSigningDetails = reconciledPkg.signingDetails;
14050 
14051         if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
14052             for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
14053                 final String codePathString = changedAbiCodePath.get(i);
14054                 try {
14055                     mInstaller.rmdex(codePathString,
14056                             getDexCodeInstructionSet(getPreferredInstructionSet()));
14057                 } catch (InstallerException ignored) {
14058                 }
14059             }
14060         }
14061 
14062         final int userId = user == null ? 0 : user.getIdentifier();
14063         // Modify state for the given package setting
14064         commitPackageSettings(pkg, oldPkg, pkgSetting, oldPkgSetting, scanFlags,
14065                 (parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0 /*chatty*/, reconciledPkg);
14066         if (pkgSetting.getInstantApp(userId)) {
14067             mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
14068         }
14069         pkgSetting.setStatesOnCommit();
14070 
14071         return pkg;
14072     }
14073 
14074     /**
14075      * Returns the "real" name of the package.
14076      * <p>This may differ from the package's actual name if the application has already
14077      * been installed under one of this package's original names.
14078      */
14079     private static @Nullable String getRealPackageName(@NonNull AndroidPackage pkg,
14080             @Nullable String renamedPkgName) {
14081         if (isPackageRenamed(pkg, renamedPkgName)) {
14082             return pkg.getRealPackage();
14083         }
14084         return null;
14085     }
14086 
14087     /** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */
14088     private static boolean isPackageRenamed(@NonNull AndroidPackage pkg,
14089             @Nullable String renamedPkgName) {
14090         return pkg.getOriginalPackages().contains(renamedPkgName);
14091     }
14092 
14093     /**
14094      * Returns the original package setting.
14095      * <p>A package can migrate its name during an update. In this scenario, a package
14096      * designates a set of names that it considers as one of its original names.
14097      * <p>An original package must be signed identically and it must have the same
14098      * shared user [if any].
14099      */
14100     @GuardedBy("mLock")
14101     private @Nullable PackageSetting getOriginalPackageLocked(@NonNull AndroidPackage pkg,
14102             @Nullable String renamedPkgName) {
14103         if (isPackageRenamed(pkg, renamedPkgName)) {
14104             return null;
14105         }
14106         for (int i = ArrayUtils.size(pkg.getOriginalPackages()) - 1; i >= 0; --i) {
14107             final PackageSetting originalPs =
14108                     mSettings.getPackageLPr(pkg.getOriginalPackages().get(i));
14109             if (originalPs != null) {
14110                 // the package is already installed under its original name...
14111                 // but, should we use it?
14112                 if (!verifyPackageUpdateLPr(originalPs, pkg)) {
14113                     // the new package is incompatible with the original
14114                     continue;
14115                 } else if (originalPs.sharedUser != null) {
14116                     if (!originalPs.sharedUser.name.equals(pkg.getSharedUserId())) {
14117                         // the shared user id is incompatible with the original
14118                         Slog.w(TAG, "Unable to migrate data from " + originalPs.name
14119                                 + " to " + pkg.getPackageName() + ": old uid "
14120                                 + originalPs.sharedUser.name
14121                                 + " differs from " + pkg.getSharedUserId());
14122                         continue;
14123                     }
14124                     // TODO: Add case when shared user id is added [b/28144775]
14125                 } else {
14126                     if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
14127                             + pkg.getPackageName() + " to old name " + originalPs.name);
14128                 }
14129                 return originalPs;
14130             }
14131         }
14132         return null;
14133     }
14134 
14135     /**
14136      * Renames the package if it was installed under a different name.
14137      * <p>When we've already installed the package under an original name, update
14138      * the new package so we can continue to have the old name.
14139      */
14140     private static void ensurePackageRenamed(@NonNull ParsedPackage parsedPackage,
14141             @NonNull String renamedPackageName) {
14142         if (!parsedPackage.getOriginalPackages().contains(renamedPackageName)
14143                 || parsedPackage.getPackageName().equals(renamedPackageName)) {
14144             return;
14145         }
14146         parsedPackage.setPackageName(renamedPackageName);
14147     }
14148 
14149     /**
14150      * Applies the adjusted ABI calculated by
14151      * {@link PackageAbiHelper#getAdjustedAbiForSharedUser(Set, AndroidPackage)} to all
14152      * relevant packages and settings.
14153      * @param sharedUserSetting The {@code SharedUserSetting} to adjust
14154      * @param scannedPackage the package being scanned or null
14155      * @param adjustedAbi the adjusted ABI calculated by {@link PackageAbiHelper}
14156      * @return the list of code paths that belong to packages that had their ABIs adjusted.
14157      */
14158     private static List<String> applyAdjustedAbiToSharedUser(SharedUserSetting sharedUserSetting,
14159             ParsedPackage scannedPackage, String adjustedAbi) {
14160         if (scannedPackage != null)  {
14161             scannedPackage.setPrimaryCpuAbi(adjustedAbi);
14162         }
14163         List<String> changedAbiCodePath = null;
14164         for (PackageSetting ps : sharedUserSetting.packages) {
14165             if (scannedPackage == null || !scannedPackage.getPackageName().equals(ps.name)) {
14166                 if (ps.primaryCpuAbiString != null) {
14167                     continue;
14168                 }
14169 
14170                 ps.primaryCpuAbiString = adjustedAbi;
14171                 if (ps.pkg != null) {
14172                     if (!TextUtils.equals(adjustedAbi,
14173                             AndroidPackageUtils.getRawPrimaryCpuAbi(ps.pkg))) {
14174                         if (DEBUG_ABI_SELECTION) {
14175                             Slog.i(TAG,
14176                                     "Adjusting ABI for " + ps.name + " to " + adjustedAbi
14177                                             + " (scannedPackage="
14178                                             + (scannedPackage != null ? scannedPackage : "null")
14179                                             + ")");
14180                         }
14181                         if (changedAbiCodePath == null) {
14182                             changedAbiCodePath = new ArrayList<>();
14183                         }
14184                         changedAbiCodePath.add(ps.getPathString());
14185                     }
14186                 }
14187             }
14188         }
14189         return changedAbiCodePath;
14190     }
14191 
14192     /**
14193      * Sets the enabled state of components configured through {@link SystemConfig}.
14194      * This modifies the {@link PackageSetting} object.
14195      *
14196      * TODO(b/135203078): Move this to package parsing
14197      **/
14198     static void configurePackageComponents(AndroidPackage pkg) {
14199         final ArrayMap<String, Boolean> componentsEnabledStates = SystemConfig.getInstance()
14200                 .getComponentsEnabledStates(pkg.getPackageName());
14201         if (componentsEnabledStates == null) {
14202             return;
14203         }
14204 
14205         for (int i = ArrayUtils.size(pkg.getActivities()) - 1; i >= 0; i--) {
14206             final ParsedActivity component = pkg.getActivities().get(i);
14207             final Boolean enabled = componentsEnabledStates.get(component.getName());
14208             if (enabled != null) {
14209                 component.setEnabled(enabled);
14210             }
14211         }
14212 
14213         for (int i = ArrayUtils.size(pkg.getReceivers()) - 1; i >= 0; i--) {
14214             final ParsedActivity component = pkg.getReceivers().get(i);
14215             final Boolean enabled = componentsEnabledStates.get(component.getName());
14216             if (enabled != null) {
14217                 component.setEnabled(enabled);
14218             }
14219         }
14220 
14221         for (int i = ArrayUtils.size(pkg.getProviders()) - 1; i >= 0; i--) {
14222             final ParsedProvider component = pkg.getProviders().get(i);
14223             final Boolean enabled = componentsEnabledStates.get(component.getName());
14224             if (enabled != null) {
14225                 component.setEnabled(enabled);
14226             }
14227         }
14228 
14229         for (int i = ArrayUtils.size(pkg.getServices()) - 1; i >= 0; i--) {
14230             final ParsedService component = pkg.getServices().get(i);
14231             final Boolean enabled = componentsEnabledStates.get(component.getName());
14232             if (enabled != null) {
14233                 component.setEnabled(enabled);
14234             }
14235         }
14236     }
14237 
14238 
14239     /**
14240      * Just scans the package without any side effects.
14241      * <p>Not entirely true at the moment. There is still one side effect -- this
14242      * method potentially modifies a live {@link PackageSetting} object representing
14243      * the package being scanned. This will be resolved in the future.
14244      *
14245      * @param injector injector for acquiring dependencies
14246      * @param request Information about the package to be scanned
14247      * @param isUnderFactoryTest Whether or not the device is under factory test
14248      * @param currentTime The current time, in millis
14249      * @return The results of the scan
14250      */
14251     @GuardedBy("mInstallLock")
14252     @VisibleForTesting
14253     @NonNull
14254     static ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
14255             Injector injector,
14256             boolean isUnderFactoryTest, long currentTime)
14257             throws PackageManagerException {
14258         final PackageAbiHelper packageAbiHelper = injector.getAbiHelper();
14259         final UserManagerInternal userManager = injector.getUserManagerInternal();
14260         ParsedPackage parsedPackage = request.parsedPackage;
14261         PackageSetting pkgSetting = request.pkgSetting;
14262         final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
14263         final PackageSetting originalPkgSetting = request.originalPkgSetting;
14264         final @ParseFlags int parseFlags = request.parseFlags;
14265         final @ScanFlags int scanFlags = request.scanFlags;
14266         final String realPkgName = request.realPkgName;
14267         final SharedUserSetting sharedUserSetting = request.sharedUserSetting;
14268         final UserHandle user = request.user;
14269         final boolean isPlatformPackage = request.isPlatformPackage;
14270 
14271         List<String> changedAbiCodePath = null;
14272 
14273         if (DEBUG_PACKAGE_SCANNING) {
14274             if ((parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0) {
14275                 Log.d(TAG, "Scanning package " + parsedPackage.getPackageName());
14276             }
14277         }
14278 
14279         // Initialize package source and resource directories
14280         final File destCodeFile = new File(parsedPackage.getPath());
14281 
14282         // We keep references to the derived CPU Abis from settings in oder to reuse
14283         // them in the case where we're not upgrading or booting for the first time.
14284         String primaryCpuAbiFromSettings = null;
14285         String secondaryCpuAbiFromSettings = null;
14286         boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
14287         if (!needToDeriveAbi) {
14288             if (pkgSetting != null) {
14289                 // TODO(b/154610922): if it is not first boot or upgrade, we should directly use
14290                 // API info from existing package setting. However, stub packages currently do not
14291                 // preserve ABI info, thus the special condition check here. Remove the special
14292                 // check after we fix the stub generation.
14293                 if (pkgSetting.pkg != null && pkgSetting.pkg.isStub()) {
14294                     needToDeriveAbi = true;
14295                 } else {
14296                     primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
14297                     secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
14298                 }
14299             } else {
14300                 // Re-scanning a system package after uninstalling updates; need to derive ABI
14301                 needToDeriveAbi = true;
14302             }
14303         }
14304 
14305         if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) {
14306             PackageManagerService.reportSettingsProblem(Log.WARN,
14307                     "Package " + parsedPackage.getPackageName() + " shared user changed from "
14308                             + (pkgSetting.sharedUser != null
14309                             ? pkgSetting.sharedUser.name : "<nothing>")
14310                             + " to "
14311                             + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
14312                             + "; replacing with new");
14313             pkgSetting = null;
14314         }
14315 
14316         String[] usesStaticLibraries = null;
14317         if (!parsedPackage.getUsesStaticLibraries().isEmpty()) {
14318             usesStaticLibraries = new String[parsedPackage.getUsesStaticLibraries().size()];
14319             parsedPackage.getUsesStaticLibraries().toArray(usesStaticLibraries);
14320         }
14321 
14322         final UUID newDomainSetId = injector.getDomainVerificationManagerInternal().generateNewId();
14323 
14324         // TODO(b/135203078): Remove appInfoFlag usage in favor of individually assigned booleans
14325         //  to avoid adding something that's unsupported due to lack of state, since it's called
14326         //  with null.
14327         final boolean createNewPackage = (pkgSetting == null);
14328         if (createNewPackage) {
14329             final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
14330             final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
14331 
14332             // Flags contain system values stored in the server variant of AndroidPackage,
14333             // and so the server-side PackageInfoUtils is still called, even without a
14334             // PackageSetting to pass in.
14335             int pkgFlags = PackageInfoUtils.appInfoFlags(parsedPackage, null);
14336             int pkgPrivateFlags = PackageInfoUtils.appInfoPrivateFlags(parsedPackage, null);
14337 
14338             // REMOVE SharedUserSetting from method; update in a separate call
14339             pkgSetting = Settings.createNewSetting(parsedPackage.getPackageName(),
14340                     originalPkgSetting, disabledPkgSetting, realPkgName, sharedUserSetting,
14341                     destCodeFile, parsedPackage.getNativeLibraryRootDir(),
14342                     AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage),
14343                     AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage),
14344                     parsedPackage.getVersionCode(), pkgFlags, pkgPrivateFlags, user,
14345                     true /*allowInstall*/, instantApp, virtualPreload,
14346                     UserManagerService.getInstance(), usesStaticLibraries,
14347                     parsedPackage.getUsesStaticLibrariesVersions(), parsedPackage.getMimeGroups(),
14348                     newDomainSetId);
14349         } else {
14350             // make a deep copy to avoid modifying any existing system state.
14351             pkgSetting = new PackageSetting(pkgSetting);
14352             pkgSetting.pkg = parsedPackage;
14353 
14354             // REMOVE SharedUserSetting from method; update in a separate call.
14355             //
14356             // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
14357             // secondaryCpuAbi are not known at this point so we always update them
14358             // to null here, only to reset them at a later point.
14359             Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting,
14360                     destCodeFile, parsedPackage.getNativeLibraryDir(),
14361                     AndroidPackageUtils.getPrimaryCpuAbi(parsedPackage, pkgSetting),
14362                     AndroidPackageUtils.getSecondaryCpuAbi(parsedPackage, pkgSetting),
14363                     PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting),
14364                     PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting),
14365                     UserManagerService.getInstance(),
14366                     usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions(),
14367                     parsedPackage.getMimeGroups(), newDomainSetId);
14368         }
14369         if (createNewPackage && originalPkgSetting != null) {
14370             // This is the initial transition from the original package, so,
14371             // fix up the new package's name now. We must do this after looking
14372             // up the package under its new name, so getPackageLP takes care of
14373             // fiddling things correctly.
14374             parsedPackage.setPackageName(originalPkgSetting.name);
14375 
14376             // File a report about this.
14377             String msg = "New package " + pkgSetting.realName
14378                     + " renamed to replace old package " + pkgSetting.name;
14379             reportSettingsProblem(Log.WARN, msg);
14380         }
14381 
14382         final int userId = (user == null ? UserHandle.USER_SYSTEM : user.getIdentifier());
14383         // for existing packages, change the install state; but, only if it's explicitly specified
14384         if (!createNewPackage) {
14385             final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
14386             final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
14387             setInstantAppForUser(injector, pkgSetting, userId, instantApp, fullApp);
14388         }
14389         // TODO(patb): see if we can do away with disabled check here.
14390         if (disabledPkgSetting != null
14391                 || (0 != (scanFlags & SCAN_NEW_INSTALL)
14392                 && pkgSetting != null && pkgSetting.isSystem())) {
14393             pkgSetting.getPkgState().setUpdatedSystemApp(true);
14394         }
14395 
14396         parsedPackage
14397                 .setSeInfo(SELinuxMMAC.getSeInfo(parsedPackage, sharedUserSetting,
14398                         injector.getCompatibility()))
14399                 .setSeInfoUser(SELinuxUtil.assignSeinfoUser(pkgSetting.readUserState(
14400                         userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM : userId)));
14401 
14402         if (parsedPackage.isSystem()) {
14403             configurePackageComponents(parsedPackage);
14404         }
14405 
14406         final String cpuAbiOverride = deriveAbiOverride(request.cpuAbiOverride);
14407         final boolean isUpdatedSystemApp = pkgSetting.getPkgState().isUpdatedSystemApp();
14408 
14409         final File appLib32InstallDir = getAppLib32InstallDir();
14410         if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
14411             if (needToDeriveAbi) {
14412                 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
14413                 final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> derivedAbi =
14414                         packageAbiHelper.derivePackageAbi(parsedPackage, isUpdatedSystemApp,
14415                                 cpuAbiOverride, appLib32InstallDir);
14416                 derivedAbi.first.applyTo(parsedPackage);
14417                 derivedAbi.second.applyTo(parsedPackage);
14418                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14419 
14420                 // Some system apps still use directory structure for native libraries
14421                 // in which case we might end up not detecting abi solely based on apk
14422                 // structure. Try to detect abi based on directory structure.
14423 
14424                 String pkgRawPrimaryCpuAbi = AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage);
14425                 if (parsedPackage.isSystem() && !isUpdatedSystemApp
14426                         && pkgRawPrimaryCpuAbi == null) {
14427                     final PackageAbiHelper.Abis abis = packageAbiHelper.getBundledAppAbis(
14428                             parsedPackage);
14429                     abis.applyTo(parsedPackage);
14430                     abis.applyTo(pkgSetting);
14431                     final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
14432                             packageAbiHelper.deriveNativeLibraryPaths(parsedPackage,
14433                                     isUpdatedSystemApp, appLib32InstallDir);
14434                     nativeLibraryPaths.applyTo(parsedPackage);
14435                 }
14436             } else {
14437                 // This is not a first boot or an upgrade, don't bother deriving the
14438                 // ABI during the scan. Instead, trust the value that was stored in the
14439                 // package setting.
14440                 parsedPackage.setPrimaryCpuAbi(primaryCpuAbiFromSettings)
14441                         .setSecondaryCpuAbi(secondaryCpuAbiFromSettings);
14442 
14443                 final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
14444                         packageAbiHelper.deriveNativeLibraryPaths(parsedPackage,
14445                                 isUpdatedSystemApp, appLib32InstallDir);
14446                 nativeLibraryPaths.applyTo(parsedPackage);
14447 
14448                 if (DEBUG_ABI_SELECTION) {
14449                     Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
14450                             parsedPackage.getPackageName() + " " +
14451                             AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage)
14452                             + ", "
14453                             + AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage));
14454                 }
14455             }
14456         } else {
14457             if ((scanFlags & SCAN_MOVE) != 0) {
14458                 // We haven't run dex-opt for this move (since we've moved the compiled output too)
14459                 // but we already have this packages package info in the PackageSetting. We just
14460                 // use that and derive the native library path based on the new codepath.
14461                 parsedPackage.setPrimaryCpuAbi(pkgSetting.primaryCpuAbiString)
14462                         .setSecondaryCpuAbi(pkgSetting.secondaryCpuAbiString);
14463             }
14464 
14465             // Set native library paths again. For moves, the path will be updated based on the
14466             // ABIs we've determined above. For non-moves, the path will be updated based on the
14467             // ABIs we determined during compilation, but the path will depend on the final
14468             // package path (after the rename away from the stage path).
14469             final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
14470                     packageAbiHelper.deriveNativeLibraryPaths(parsedPackage, isUpdatedSystemApp,
14471                             appLib32InstallDir);
14472             nativeLibraryPaths.applyTo(parsedPackage);
14473         }
14474 
14475         // This is a special case for the "system" package, where the ABI is
14476         // dictated by the zygote configuration (and init.rc). We should keep track
14477         // of this ABI so that we can deal with "normal" applications that run under
14478         // the same UID correctly.
14479         if (isPlatformPackage) {
14480             parsedPackage.setPrimaryCpuAbi(VMRuntime.getRuntime().is64Bit() ?
14481                     Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]);
14482         }
14483 
14484         // If there's a mismatch between the abi-override in the package setting
14485         // and the abiOverride specified for the install. Warn about this because we
14486         // would've already compiled the app without taking the package setting into
14487         // account.
14488         if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
14489             if (cpuAbiOverride == null) {
14490                 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
14491                         " for package " + parsedPackage.getPackageName());
14492             }
14493         }
14494 
14495         pkgSetting.primaryCpuAbiString = AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage);
14496         pkgSetting.secondaryCpuAbiString = AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage);
14497         pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
14498 
14499         if (DEBUG_ABI_SELECTION) {
14500             Slog.d(TAG, "Resolved nativeLibraryRoot for " + parsedPackage.getPackageName()
14501                     + " to root=" + parsedPackage.getNativeLibraryRootDir()
14502                     + ", to dir=" + parsedPackage.getNativeLibraryDir()
14503                     + ", isa=" + parsedPackage.isNativeLibraryRootRequiresIsa());
14504         }
14505 
14506         // Push the derived path down into PackageSettings so we know what to
14507         // clean up at uninstall time.
14508         pkgSetting.legacyNativeLibraryPathString = parsedPackage.getNativeLibraryRootDir();
14509 
14510         if (DEBUG_ABI_SELECTION) {
14511             Log.d(TAG, "Abis for package[" + parsedPackage.getPackageName() + "] are"
14512                     + " primary=" + pkgSetting.primaryCpuAbiString
14513                     + " secondary=" + pkgSetting.primaryCpuAbiString
14514                     + " abiOverride=" + pkgSetting.cpuAbiOverrideString);
14515         }
14516 
14517         if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
14518             // We don't do this here during boot because we can do it all
14519             // at once after scanning all existing packages.
14520             //
14521             // We also do this *before* we perform dexopt on this package, so that
14522             // we can avoid redundant dexopts, and also to make sure we've got the
14523             // code and package path correct.
14524             changedAbiCodePath = applyAdjustedAbiToSharedUser(pkgSetting.sharedUser, parsedPackage,
14525                     packageAbiHelper.getAdjustedAbiForSharedUser(
14526                             pkgSetting.sharedUser.packages, parsedPackage));
14527         }
14528 
14529         parsedPackage.setFactoryTest(isUnderFactoryTest && parsedPackage.getRequestedPermissions()
14530                 .contains(android.Manifest.permission.FACTORY_TEST));
14531 
14532         if (parsedPackage.isSystem()) {
14533             pkgSetting.setIsOrphaned(true);
14534         }
14535 
14536         // Take care of first install / last update times.
14537         final long scanFileTime = getLastModifiedTime(parsedPackage);
14538         if (currentTime != 0) {
14539             if (pkgSetting.firstInstallTime == 0) {
14540                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
14541             } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
14542                 pkgSetting.lastUpdateTime = currentTime;
14543             }
14544         } else if (pkgSetting.firstInstallTime == 0) {
14545             // We need *something*.  Take time time stamp of the file.
14546             pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
14547         } else if ((parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) != 0) {
14548             if (scanFileTime != pkgSetting.timeStamp) {
14549                 // A package on the system image has changed; consider this
14550                 // to be an update.
14551                 pkgSetting.lastUpdateTime = scanFileTime;
14552             }
14553         }
14554         pkgSetting.setTimeStamp(scanFileTime);
14555         // TODO(b/135203078): Remove, move to constructor
14556         pkgSetting.pkg = parsedPackage;
14557         pkgSetting.pkgFlags = PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting);
14558         pkgSetting.pkgPrivateFlags =
14559                 PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting);
14560         if (parsedPackage.getLongVersionCode() != pkgSetting.versionCode) {
14561             pkgSetting.versionCode = parsedPackage.getLongVersionCode();
14562         }
14563         // Update volume if needed
14564         final String volumeUuid = parsedPackage.getVolumeUuid();
14565         if (!Objects.equals(volumeUuid, pkgSetting.volumeUuid)) {
14566             Slog.i(PackageManagerService.TAG,
14567                     "Update" + (pkgSetting.isSystem() ? " system" : "")
14568                     + " package " + parsedPackage.getPackageName()
14569                     + " volume from " + pkgSetting.volumeUuid
14570                     + " to " + volumeUuid);
14571             pkgSetting.volumeUuid = volumeUuid;
14572         }
14573 
14574         SharedLibraryInfo staticSharedLibraryInfo = null;
14575         if (!TextUtils.isEmpty(parsedPackage.getStaticSharedLibName())) {
14576             staticSharedLibraryInfo =
14577                     AndroidPackageUtils.createSharedLibraryForStatic(parsedPackage);
14578         }
14579         List<SharedLibraryInfo> dynamicSharedLibraryInfos = null;
14580         if (!ArrayUtils.isEmpty(parsedPackage.getLibraryNames())) {
14581             dynamicSharedLibraryInfos = new ArrayList<>(parsedPackage.getLibraryNames().size());
14582             for (String name : parsedPackage.getLibraryNames()) {
14583                 dynamicSharedLibraryInfos.add(
14584                         AndroidPackageUtils.createSharedLibraryForDynamic(parsedPackage, name));
14585             }
14586         }
14587 
14588         return new ScanResult(request, true, pkgSetting, changedAbiCodePath,
14589                 !createNewPackage /* existingSettingCopied */, staticSharedLibraryInfo,
14590                 dynamicSharedLibraryInfos);
14591     }
14592 
14593     /**
14594      * Returns {@code true} if the given file contains code. Otherwise {@code false}.
14595      */
14596     private static boolean apkHasCode(String fileName) {
14597         StrictJarFile jarFile = null;
14598         try {
14599             jarFile = new StrictJarFile(fileName,
14600                     false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
14601             return jarFile.findEntry("classes.dex") != null;
14602         } catch (IOException ignore) {
14603         } finally {
14604             try {
14605                 if (jarFile != null) {
14606                     jarFile.close();
14607                 }
14608             } catch (IOException ignore) {}
14609         }
14610         return false;
14611     }
14612 
14613     /**
14614      * Enforces code policy for the package. This ensures that if an APK has
14615      * declared hasCode="true" in its manifest that the APK actually contains
14616      * code.
14617      *
14618      * @throws PackageManagerException If bytecode could not be found when it should exist
14619      */
14620     private static void assertCodePolicy(AndroidPackage pkg)
14621             throws PackageManagerException {
14622         final boolean shouldHaveCode = pkg.isHasCode();
14623         if (shouldHaveCode && !apkHasCode(pkg.getBaseApkPath())) {
14624             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
14625                     "Package " + pkg.getBaseApkPath() + " code is missing");
14626         }
14627 
14628         if (!ArrayUtils.isEmpty(pkg.getSplitCodePaths())) {
14629             for (int i = 0; i < pkg.getSplitCodePaths().length; i++) {
14630                 final boolean splitShouldHaveCode =
14631                         (pkg.getSplitFlags()[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
14632                 if (splitShouldHaveCode && !apkHasCode(pkg.getSplitCodePaths()[i])) {
14633                     throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
14634                             "Package " + pkg.getSplitCodePaths()[i] + " code is missing");
14635                 }
14636             }
14637         }
14638     }
14639 
14640     /**
14641      * Applies policy to the parsed package based upon the given policy flags.
14642      * Ensures the package is in a good state.
14643      * <p>
14644      * Implementation detail: This method must NOT have any side effect. It would
14645      * ideally be static, but, it requires locks to read system state.
14646      */
14647     private static void applyPolicy(ParsedPackage parsedPackage, final @ParseFlags int parseFlags,
14648             final @ScanFlags int scanFlags, AndroidPackage platformPkg,
14649             boolean isUpdatedSystemApp) {
14650         if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
14651             parsedPackage.setSystem(true);
14652             // TODO(b/135203078): Can this be done in PackageParser? Or just inferred when the flag
14653             //  is set during parse.
14654             if (parsedPackage.isDirectBootAware()) {
14655                 parsedPackage.setAllComponentsDirectBootAware(true);
14656             }
14657             if (compressedFileExists(parsedPackage.getPath())) {
14658                 parsedPackage.setStub(true);
14659             }
14660         } else {
14661             parsedPackage
14662                     // Non system apps cannot mark any broadcast as protected
14663                     .clearProtectedBroadcasts()
14664                     // non system apps can't be flagged as core
14665                     .setCoreApp(false)
14666                     // clear flags not applicable to regular apps
14667                     .setPersistent(false)
14668                     .setDefaultToDeviceProtectedStorage(false)
14669                     .setDirectBootAware(false)
14670                     // non system apps can't have permission priority
14671                     .capPermissionPriorities();
14672         }
14673         if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
14674             parsedPackage
14675                     .markNotActivitiesAsNotExportedIfSingleUser();
14676         }
14677 
14678         parsedPackage.setPrivileged((scanFlags & SCAN_AS_PRIVILEGED) != 0)
14679                 .setOem((scanFlags & SCAN_AS_OEM) != 0)
14680                 .setVendor((scanFlags & SCAN_AS_VENDOR) != 0)
14681                 .setProduct((scanFlags & SCAN_AS_PRODUCT) != 0)
14682                 .setSystemExt((scanFlags & SCAN_AS_SYSTEM_EXT) != 0)
14683                 .setOdm((scanFlags & SCAN_AS_ODM) != 0);
14684 
14685         // Check if the package is signed with the same key as the platform package.
14686         parsedPackage.setSignedWithPlatformKey(
14687                 (PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())
14688                         || (platformPkg != null && compareSignatures(
14689                         platformPkg.getSigningDetails().signatures,
14690                         parsedPackage.getSigningDetails().signatures
14691                 ) == PackageManager.SIGNATURE_MATCH))
14692         );
14693 
14694         if (!parsedPackage.isSystem()) {
14695             // Only system apps can use these features.
14696             parsedPackage.clearOriginalPackages()
14697                     .setRealPackage(null)
14698                     .clearAdoptPermissions();
14699         }
14700 
14701         PackageBackwardCompatibility.modifySharedLibraries(parsedPackage, isUpdatedSystemApp);
14702     }
14703 
14704     private static @NonNull <T> T assertNotNull(@Nullable T object, String message)
14705             throws PackageManagerException {
14706         if (object == null) {
14707             throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, message);
14708         }
14709         return object;
14710     }
14711 
14712     private <T extends ParsedMainComponent>
14713             void assertPackageProcesses(AndroidPackage pkg, List<T> components,
14714             Map<String, ParsedProcess> procs, String compName)
14715             throws PackageManagerException {
14716         if (components == null) {
14717             return;
14718         }
14719         for (int i = components.size() - 1; i >= 0; i--) {
14720             final ParsedMainComponent component = components.get(i);
14721             if (!procs.containsKey(component.getProcessName())) {
14722                 throw new PackageManagerException(
14723                         INSTALL_FAILED_PROCESS_NOT_DEFINED,
14724                         "Can't install because " + compName + " " + component.getClassName()
14725                                 + "'s process attribute " + component.getProcessName()
14726                                 + " (in package " + pkg.getPackageName()
14727                                 + ") is not included in the <processes> list");
14728             }
14729         }
14730     }
14731 
14732     /**
14733      * Asserts the parsed package is valid according to the given policy. If the
14734      * package is invalid, for whatever reason, throws {@link PackageManagerException}.
14735      * <p>
14736      * Implementation detail: This method must NOT have any side effects. It would
14737      * ideally be static, but, it requires locks to read system state.
14738      *
14739      * @throws PackageManagerException If the package fails any of the validation checks
14740      */
14741     private void assertPackageIsValid(AndroidPackage pkg, final @ParseFlags int parseFlags,
14742             final @ScanFlags int scanFlags)
14743                     throws PackageManagerException {
14744         if ((parseFlags & ParsingPackageUtils.PARSE_ENFORCE_CODE) != 0) {
14745             assertCodePolicy(pkg);
14746         }
14747 
14748         if (pkg.getPath() == null) {
14749             // Bail out. The resource and code paths haven't been set.
14750             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
14751                     "Code and resource paths haven't been set correctly");
14752         }
14753 
14754         // Check that there is an APEX package with the same name only during install/first boot
14755         // after OTA.
14756         final boolean isUserInstall = (scanFlags & SCAN_BOOTING) == 0;
14757         final boolean isFirstBootOrUpgrade = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
14758         if ((isUserInstall || isFirstBootOrUpgrade)
14759                 && mApexManager.isApexPackage(pkg.getPackageName())) {
14760             throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
14761                     pkg.getPackageName()
14762                             + " is an APEX package and can't be installed as an APK.");
14763         }
14764 
14765         // Make sure we're not adding any bogus keyset info
14766         final KeySetManagerService ksms = mSettings.getKeySetManagerService();
14767         ksms.assertScannedPackageValid(pkg);
14768 
14769         synchronized (mLock) {
14770             // The special "android" package can only be defined once
14771             if (pkg.getPackageName().equals("android")) {
14772                 if (mAndroidApplication != null) {
14773                     Slog.w(TAG, "*************************************************");
14774                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
14775                     Slog.w(TAG, " codePath=" + pkg.getPath());
14776                     Slog.w(TAG, "*************************************************");
14777                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
14778                             "Core android package being redefined.  Skipping.");
14779                 }
14780             }
14781 
14782             // A package name must be unique; don't allow duplicates
14783             if ((scanFlags & SCAN_NEW_INSTALL) == 0
14784                     && mPackages.containsKey(pkg.getPackageName())) {
14785                 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
14786                         "Application package " + pkg.getPackageName()
14787                         + " already installed.  Skipping duplicate.");
14788             }
14789 
14790             if (pkg.isStaticSharedLibrary()) {
14791                 // Static libs have a synthetic package name containing the version
14792                 // but we still want the base name to be unique.
14793                 if ((scanFlags & SCAN_NEW_INSTALL) == 0
14794                         && mPackages.containsKey(pkg.getManifestPackageName())) {
14795                     throw new PackageManagerException(
14796                             "Duplicate static shared lib provider package");
14797                 }
14798 
14799                 // Static shared libraries should have at least O target SDK
14800                 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
14801                     throw new PackageManagerException(
14802                             "Packages declaring static-shared libs must target O SDK or higher");
14803                 }
14804 
14805                 // Package declaring static a shared lib cannot be instant apps
14806                 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
14807                     throw new PackageManagerException(
14808                             "Packages declaring static-shared libs cannot be instant apps");
14809                 }
14810 
14811                 // Package declaring static a shared lib cannot be renamed since the package
14812                 // name is synthetic and apps can't code around package manager internals.
14813                 if (!ArrayUtils.isEmpty(pkg.getOriginalPackages())) {
14814                     throw new PackageManagerException(
14815                             "Packages declaring static-shared libs cannot be renamed");
14816                 }
14817 
14818                 // Package declaring static a shared lib cannot declare dynamic libs
14819                 if (!ArrayUtils.isEmpty(pkg.getLibraryNames())) {
14820                     throw new PackageManagerException(
14821                             "Packages declaring static-shared libs cannot declare dynamic libs");
14822                 }
14823 
14824                 // Package declaring static a shared lib cannot declare shared users
14825                 if (pkg.getSharedUserId() != null) {
14826                     throw new PackageManagerException(
14827                             "Packages declaring static-shared libs cannot declare shared users");
14828                 }
14829 
14830                 // Static shared libs cannot declare activities
14831                 if (!pkg.getActivities().isEmpty()) {
14832                     throw new PackageManagerException(
14833                             "Static shared libs cannot declare activities");
14834                 }
14835 
14836                 // Static shared libs cannot declare services
14837                 if (!pkg.getServices().isEmpty()) {
14838                     throw new PackageManagerException(
14839                             "Static shared libs cannot declare services");
14840                 }
14841 
14842                 // Static shared libs cannot declare providers
14843                 if (!pkg.getProviders().isEmpty()) {
14844                     throw new PackageManagerException(
14845                             "Static shared libs cannot declare content providers");
14846                 }
14847 
14848                 // Static shared libs cannot declare receivers
14849                 if (!pkg.getReceivers().isEmpty()) {
14850                     throw new PackageManagerException(
14851                             "Static shared libs cannot declare broadcast receivers");
14852                 }
14853 
14854                 // Static shared libs cannot declare permission groups
14855                 if (!pkg.getPermissionGroups().isEmpty()) {
14856                     throw new PackageManagerException(
14857                             "Static shared libs cannot declare permission groups");
14858                 }
14859 
14860                 // Static shared libs cannot declare attributions
14861                 if (!pkg.getAttributions().isEmpty()) {
14862                     throw new PackageManagerException(
14863                             "Static shared libs cannot declare features");
14864                 }
14865 
14866                 // Static shared libs cannot declare permissions
14867                 if (!pkg.getPermissions().isEmpty()) {
14868                     throw new PackageManagerException(
14869                             "Static shared libs cannot declare permissions");
14870                 }
14871 
14872                 // Static shared libs cannot declare protected broadcasts
14873                 if (!pkg.getProtectedBroadcasts().isEmpty()) {
14874                     throw new PackageManagerException(
14875                             "Static shared libs cannot declare protected broadcasts");
14876                 }
14877 
14878                 // Static shared libs cannot be overlay targets
14879                 if (pkg.getOverlayTarget() != null) {
14880                     throw new PackageManagerException(
14881                             "Static shared libs cannot be overlay targets");
14882                 }
14883 
14884                 // The version codes must be ordered as lib versions
14885                 long minVersionCode = Long.MIN_VALUE;
14886                 long maxVersionCode = Long.MAX_VALUE;
14887 
14888                 WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(
14889                         pkg.getStaticSharedLibName());
14890                 if (versionedLib != null) {
14891                     final int versionCount = versionedLib.size();
14892                     for (int i = 0; i < versionCount; i++) {
14893                         SharedLibraryInfo libInfo = versionedLib.valueAt(i);
14894                         final long libVersionCode = libInfo.getDeclaringPackage()
14895                                 .getLongVersionCode();
14896                         if (libInfo.getLongVersion() < pkg.getStaticSharedLibVersion()) {
14897                             minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
14898                         } else if (libInfo.getLongVersion()
14899                                 > pkg.getStaticSharedLibVersion()) {
14900                             maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
14901                         } else {
14902                             minVersionCode = maxVersionCode = libVersionCode;
14903                             break;
14904                         }
14905                     }
14906                 }
14907                 if (pkg.getLongVersionCode() < minVersionCode
14908                         || pkg.getLongVersionCode() > maxVersionCode) {
14909                     throw new PackageManagerException("Static shared"
14910                             + " lib version codes must be ordered as lib versions");
14911                 }
14912             }
14913 
14914             // If we're only installing presumed-existing packages, require that the
14915             // scanned APK is both already known and at the path previously established
14916             // for it.  Previously unknown packages we pick up normally, but if we have an
14917             // a priori expectation about this package's install presence, enforce it.
14918             // With a singular exception for new system packages. When an OTA contains
14919             // a new system package, we allow the codepath to change from a system location
14920             // to the user-installed location. If we don't allow this change, any newer,
14921             // user-installed version of the application will be ignored.
14922             if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
14923                 if (mExpectingBetter.containsKey(pkg.getPackageName())) {
14924                     Slog.w(TAG, "Relax SCAN_REQUIRE_KNOWN requirement for package "
14925                             + pkg.getPackageName());
14926                 } else {
14927                     PackageSetting known = mSettings.getPackageLPr(pkg.getPackageName());
14928                     if (known != null) {
14929                         if (DEBUG_PACKAGE_SCANNING) {
14930                             Log.d(TAG, "Examining " + pkg.getPath()
14931                                     + " and requiring known path " + known.getPathString());
14932                         }
14933                         if (!pkg.getPath().equals(known.getPathString())) {
14934                             throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
14935                                     "Application package " + pkg.getPackageName()
14936                                     + " found at " + pkg.getPath()
14937                                     + " but expected at " + known.getPathString()
14938                                     + "; ignoring.");
14939                         }
14940                     } else {
14941                         throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
14942                                 "Application package " + pkg.getPackageName()
14943                                 + " not found; ignoring.");
14944                     }
14945                 }
14946             }
14947 
14948             // Verify that this new package doesn't have any content providers
14949             // that conflict with existing packages.  Only do this if the
14950             // package isn't already installed, since we don't want to break
14951             // things that are installed.
14952             if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
14953                 mComponentResolver.assertProvidersNotDefined(pkg);
14954             }
14955 
14956             // If this package has defined explicit processes, then ensure that these are
14957             // the only processes used by its components.
14958             final Map<String, ParsedProcess> procs = pkg.getProcesses();
14959             if (!procs.isEmpty()) {
14960                 if (!procs.containsKey(pkg.getProcessName())) {
14961                     throw new PackageManagerException(
14962                             INSTALL_FAILED_PROCESS_NOT_DEFINED,
14963                             "Can't install because application tag's process attribute "
14964                                     + pkg.getProcessName()
14965                                     + " (in package " + pkg.getPackageName()
14966                                     + ") is not included in the <processes> list");
14967                 }
14968                 assertPackageProcesses(pkg, pkg.getActivities(), procs, "activity");
14969                 assertPackageProcesses(pkg, pkg.getServices(), procs, "service");
14970                 assertPackageProcesses(pkg, pkg.getReceivers(), procs, "receiver");
14971                 assertPackageProcesses(pkg, pkg.getProviders(), procs, "provider");
14972             }
14973 
14974             // Verify that packages sharing a user with a privileged app are marked as privileged.
14975             if (!pkg.isPrivileged() && (pkg.getSharedUserId() != null)) {
14976                 SharedUserSetting sharedUserSetting = null;
14977                 try {
14978                     sharedUserSetting = mSettings.getSharedUserLPw(pkg.getSharedUserId(),
14979                             0, 0, false);
14980                 } catch (PackageManagerException ignore) {
14981                 }
14982                 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
14983                     // Exempt SharedUsers signed with the platform key.
14984                     PackageSetting platformPkgSetting = mSettings.getPackageLPr("android");
14985                     if (!comparePackageSignatures(platformPkgSetting,
14986                             pkg.getSigningDetails().signatures)) {
14987                         throw new PackageManagerException("Apps that share a user with a " +
14988                                 "privileged app must themselves be marked as privileged. " +
14989                                 pkg.getPackageName() + " shares privileged user " +
14990                                 pkg.getSharedUserId() + ".");
14991                     }
14992                 }
14993             }
14994 
14995             // Apply policies specific for runtime resource overlays (RROs).
14996             if (pkg.getOverlayTarget() != null) {
14997                 // System overlays have some restrictions on their use of the 'static' state.
14998                 if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
14999                     // We are scanning a system overlay. This can be the first scan of the
15000                     // system/vendor/oem partition, or an update to the system overlay.
15001                     if ((parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) == 0) {
15002                         // This must be an update to a system overlay. Immutable overlays cannot be
15003                         // upgraded.
15004                         Objects.requireNonNull(mOverlayConfig,
15005                                 "Parsing non-system dir before overlay configs are initialized");
15006                         if (!mOverlayConfig.isMutable(pkg.getPackageName())) {
15007                             throw new PackageManagerException("Overlay "
15008                                     + pkg.getPackageName()
15009                                     + " is static and cannot be upgraded.");
15010                         }
15011                     } else {
15012                         if ((scanFlags & SCAN_AS_VENDOR) != 0) {
15013                             if (pkg.getTargetSdkVersion() < getVendorPartitionVersion()) {
15014                                 Slog.w(TAG, "System overlay " + pkg.getPackageName()
15015                                         + " targets an SDK below the required SDK level of vendor"
15016                                         + " overlays (" + getVendorPartitionVersion() + ")."
15017                                         + " This will become an install error in a future release");
15018                             }
15019                         } else if (pkg.getTargetSdkVersion() < Build.VERSION.SDK_INT) {
15020                             Slog.w(TAG, "System overlay " + pkg.getPackageName()
15021                                     + " targets an SDK below the required SDK level of system"
15022                                     + " overlays (" + Build.VERSION.SDK_INT + ")."
15023                                     + " This will become an install error in a future release");
15024                         }
15025                     }
15026                 } else {
15027                     // A non-preloaded overlay packages must have targetSdkVersion >= Q, or be
15028                     // signed with the platform certificate. Check this in increasing order of
15029                     // computational cost.
15030                     if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.Q) {
15031                         final PackageSetting platformPkgSetting =
15032                                 mSettings.getPackageLPr("android");
15033                         if (!comparePackageSignatures(platformPkgSetting,
15034                                 pkg.getSigningDetails().signatures)) {
15035                             throw new PackageManagerException("Overlay "
15036                                     + pkg.getPackageName()
15037                                     + " must target Q or later, "
15038                                     + "or be signed with the platform certificate");
15039                         }
15040                     }
15041 
15042                     // A non-preloaded overlay package, without <overlay android:targetName>, will
15043                     // only be used if it is signed with the same certificate as its target OR if
15044                     // it is signed with the same certificate as a reference package declared
15045                     // in 'overlay-config-signature' tag of SystemConfig.
15046                     // If the target is already installed or 'overlay-config-signature' tag in
15047                     // SystemConfig is set, check this here to augment the last line of defense
15048                     // which is OMS.
15049                     if (pkg.getOverlayTargetName() == null) {
15050                         final PackageSetting targetPkgSetting =
15051                                 mSettings.getPackageLPr(pkg.getOverlayTarget());
15052                         if (targetPkgSetting != null) {
15053                             if (!comparePackageSignatures(targetPkgSetting,
15054                                     pkg.getSigningDetails().signatures)) {
15055                                 // check reference signature
15056                                 if (mOverlayConfigSignaturePackage == null) {
15057                                     throw new PackageManagerException("Overlay "
15058                                             + pkg.getPackageName() + " and target "
15059                                             + pkg.getOverlayTarget() + " signed with"
15060                                             + " different certificates, and the overlay lacks"
15061                                             + " <overlay android:targetName>");
15062                                 }
15063                                 final PackageSetting refPkgSetting =
15064                                         mSettings.getPackageLPr(mOverlayConfigSignaturePackage);
15065                                 if (!comparePackageSignatures(refPkgSetting,
15066                                         pkg.getSigningDetails().signatures)) {
15067                                     throw new PackageManagerException("Overlay "
15068                                             + pkg.getPackageName() + " signed with a different "
15069                                             + "certificate than both the reference package and "
15070                                             + "target " + pkg.getOverlayTarget() + ", and the "
15071                                             + "overlay lacks <overlay android:targetName>");
15072                                 }
15073                             }
15074                         }
15075                     }
15076                 }
15077             }
15078 
15079             // If the package is not on a system partition ensure it is signed with at least the
15080             // minimum signature scheme version required for its target SDK.
15081             if ((parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) == 0) {
15082                 int minSignatureSchemeVersion =
15083                         ApkSignatureVerifier.getMinimumSignatureSchemeVersionForTargetSdk(
15084                                 pkg.getTargetSdkVersion());
15085                 if (pkg.getSigningDetails().signatureSchemeVersion < minSignatureSchemeVersion) {
15086                     throw new PackageManagerException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
15087                             "No signature found in package of version " + minSignatureSchemeVersion
15088                                     + " or newer for package " + pkg.getPackageName());
15089                 }
15090             }
15091         }
15092     }
15093 
15094     @GuardedBy("mLock")
15095     private boolean addBuiltInSharedLibraryLocked(SystemConfig.SharedLibraryEntry entry) {
15096         if (nonStaticSharedLibExistsLocked(entry.name)) {
15097             return false;
15098         }
15099 
15100         SharedLibraryInfo libraryInfo = new SharedLibraryInfo(entry.filename, null, null,
15101                 entry.name, (long) SharedLibraryInfo.VERSION_UNDEFINED,
15102                 SharedLibraryInfo.TYPE_BUILTIN,
15103                 new VersionedPackage(PLATFORM_PACKAGE_NAME, (long)0), null, null,
15104                 entry.isNative);
15105 
15106         commitSharedLibraryInfoLocked(libraryInfo);
15107         return true;
15108     }
15109 
15110     @GuardedBy("mLock")
15111     private boolean nonStaticSharedLibExistsLocked(String name) {
15112         return sharedLibExists(name, SharedLibraryInfo.VERSION_UNDEFINED, mSharedLibraries);
15113     }
15114 
15115     private static boolean sharedLibExists(final String name, final long version,
15116             Map<String, WatchedLongSparseArray<SharedLibraryInfo>> librarySource) {
15117         WatchedLongSparseArray<SharedLibraryInfo> versionedLib = librarySource.get(name);
15118         if (versionedLib != null && versionedLib.indexOfKey(version) >= 0) {
15119             return true;
15120         }
15121         return false;
15122     }
15123 
15124     @GuardedBy("mLock")
15125     private void commitSharedLibraryInfoLocked(SharedLibraryInfo libraryInfo) {
15126         final String name = libraryInfo.getName();
15127         WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(name);
15128         if (versionedLib == null) {
15129             versionedLib = new WatchedLongSparseArray<>();
15130             mSharedLibraries.put(name, versionedLib);
15131         }
15132         final String declaringPackageName = libraryInfo.getDeclaringPackage().getPackageName();
15133         if (libraryInfo.getType() == SharedLibraryInfo.TYPE_STATIC) {
15134             mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
15135         }
15136         versionedLib.put(libraryInfo.getLongVersion(), libraryInfo);
15137     }
15138 
15139     private boolean removeSharedLibraryLPw(String name, long version) {
15140         WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(name);
15141         if (versionedLib == null) {
15142             return false;
15143         }
15144         final int libIdx = versionedLib.indexOfKey(version);
15145         if (libIdx < 0) {
15146             return false;
15147         }
15148         SharedLibraryInfo libraryInfo = versionedLib.valueAt(libIdx);
15149 
15150         // Remove the shared library overlays from its dependent packages.
15151         for (int currentUserId : UserManagerService.getInstance().getUserIds()) {
15152             final List<VersionedPackage> dependents = getPackagesUsingSharedLibraryLPr(
15153                     libraryInfo, 0, Process.SYSTEM_UID, currentUserId);
15154             if (dependents == null) {
15155                 continue;
15156             }
15157             for (VersionedPackage dependentPackage : dependents) {
15158                 final PackageSetting ps = mSettings.getPackageLPr(
15159                         dependentPackage.getPackageName());
15160                 if (ps != null) {
15161                     ps.setOverlayPathsForLibrary(libraryInfo.getName(), null, currentUserId);
15162                 }
15163             }
15164         }
15165 
15166         versionedLib.remove(version);
15167         if (versionedLib.size() <= 0) {
15168             mSharedLibraries.remove(name);
15169             if (libraryInfo.getType() == SharedLibraryInfo.TYPE_STATIC) {
15170                 mStaticLibsByDeclaringPackage.remove(libraryInfo.getDeclaringPackage()
15171                         .getPackageName());
15172             }
15173         }
15174         return true;
15175     }
15176 
15177     @Override
15178     public Property getProperty(String propertyName, String packageName, String className) {
15179         Objects.requireNonNull(propertyName);
15180         Objects.requireNonNull(packageName);
15181         synchronized (mLock) {
15182             final PackageSetting ps = getPackageSetting(packageName);
15183             if (shouldFilterApplicationLocked(ps, Binder.getCallingUid(),
15184                     UserHandle.getCallingUserId())) {
15185                 return null;
15186             }
15187             return mPackageProperty.getProperty(propertyName, packageName, className);
15188         }
15189     }
15190 
15191     @Override
15192     public ParceledListSlice<Property> queryProperty(
15193             String propertyName, @PropertyLocation int componentType) {
15194         Objects.requireNonNull(propertyName);
15195         final int callingUid = Binder.getCallingUid();
15196         final int callingUserId = UserHandle.getCallingUserId();
15197         final List<Property> result =
15198                 mPackageProperty.queryProperty(propertyName, componentType, packageName -> {
15199                     final PackageSetting ps = getPackageSetting(packageName);
15200                     return shouldFilterApplicationLocked(ps, callingUid, callingUserId);
15201                 });
15202         if (result == null) {
15203             return ParceledListSlice.emptyList();
15204         }
15205         return new ParceledListSlice<>(result);
15206     }
15207 
15208     /**
15209      * Adds a scanned package to the system. When this method is finished, the package will
15210      * be available for query, resolution, etc...
15211      */
15212     private void commitPackageSettings(@NonNull AndroidPackage pkg, @Nullable AndroidPackage oldPkg,
15213             @NonNull PackageSetting pkgSetting, @Nullable PackageSetting oldPkgSetting,
15214             final @ScanFlags int scanFlags, boolean chatty, ReconciledPackage reconciledPkg) {
15215         final String pkgName = pkg.getPackageName();
15216         if (mCustomResolverComponentName != null &&
15217                 mCustomResolverComponentName.getPackageName().equals(pkg.getPackageName())) {
15218             setUpCustomResolverActivity(pkg, pkgSetting);
15219         }
15220 
15221         if (pkg.getPackageName().equals("android")) {
15222             synchronized (mLock) {
15223                 // Set up information for our fall-back user intent resolution activity.
15224                 mPlatformPackage = pkg;
15225 
15226                 // The instance stored in PackageManagerService is special cased to be non-user
15227                 // specific, so initialize all the needed fields here.
15228                 mAndroidApplication = pkg.toAppInfoWithoutState();
15229                 mAndroidApplication.flags = PackageInfoUtils.appInfoFlags(pkg, pkgSetting);
15230                 mAndroidApplication.privateFlags =
15231                         PackageInfoUtils.appInfoPrivateFlags(pkg, pkgSetting);
15232                 mAndroidApplication.initForUser(UserHandle.USER_SYSTEM);
15233 
15234                 if (!mResolverReplaced) {
15235                     mResolveActivity.applicationInfo = mAndroidApplication;
15236                     mResolveActivity.name = ResolverActivity.class.getName();
15237                     mResolveActivity.packageName = mAndroidApplication.packageName;
15238                     mResolveActivity.processName = "system:ui";
15239                     mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
15240                     mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
15241                     mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
15242                     mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
15243                     mResolveActivity.exported = true;
15244                     mResolveActivity.enabled = true;
15245                     mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
15246                     mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
15247                             | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
15248                             | ActivityInfo.CONFIG_SCREEN_LAYOUT
15249                             | ActivityInfo.CONFIG_ORIENTATION
15250                             | ActivityInfo.CONFIG_KEYBOARD
15251                             | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
15252                     mResolveInfo.activityInfo = mResolveActivity;
15253                     mResolveInfo.priority = 0;
15254                     mResolveInfo.preferredOrder = 0;
15255                     mResolveInfo.match = 0;
15256                     mResolveComponentName = new ComponentName(
15257                             mAndroidApplication.packageName, mResolveActivity.name);
15258                 }
15259                 onChanged();
15260             }
15261         }
15262 
15263         ArrayList<AndroidPackage> clientLibPkgs = null;
15264         // writer
15265         synchronized (mLock) {
15266             if (!ArrayUtils.isEmpty(reconciledPkg.allowedSharedLibraryInfos)) {
15267                 for (SharedLibraryInfo info : reconciledPkg.allowedSharedLibraryInfos) {
15268                     commitSharedLibraryInfoLocked(info);
15269                 }
15270                 final Map<String, AndroidPackage> combinedSigningDetails =
15271                         reconciledPkg.getCombinedAvailablePackages();
15272                 try {
15273                     // Shared libraries for the package need to be updated.
15274                     updateSharedLibrariesLocked(pkg, pkgSetting, null, null,
15275                             combinedSigningDetails);
15276                 } catch (PackageManagerException e) {
15277                     Slog.e(TAG, "updateSharedLibrariesLPr failed: ", e);
15278                 }
15279                 // Update all applications that use this library. Skip when booting
15280                 // since this will be done after all packages are scaned.
15281                 if ((scanFlags & SCAN_BOOTING) == 0) {
15282                     clientLibPkgs = updateAllSharedLibrariesLocked(pkg, pkgSetting,
15283                             combinedSigningDetails);
15284                 }
15285             }
15286         }
15287         if (reconciledPkg.installResult != null) {
15288             reconciledPkg.installResult.libraryConsumers = clientLibPkgs;
15289         }
15290 
15291         if ((scanFlags & SCAN_BOOTING) != 0) {
15292             // No apps can run during boot scan, so they don't need to be frozen
15293         } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
15294             // Caller asked to not kill app, so it's probably not frozen
15295         } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
15296             // Caller asked us to ignore frozen check for some reason; they
15297             // probably didn't know the package name
15298         } else {
15299             // We're doing major surgery on this package, so it better be frozen
15300             // right now to keep it from launching
15301             checkPackageFrozen(pkgName);
15302         }
15303 
15304         // Also need to kill any apps that are dependent on the library.
15305         if (clientLibPkgs != null) {
15306             for (int i=0; i<clientLibPkgs.size(); i++) {
15307                 AndroidPackage clientPkg = clientLibPkgs.get(i);
15308                 killApplication(clientPkg.getPackageName(),
15309                         clientPkg.getUid(), "update lib");
15310             }
15311         }
15312 
15313         // writer
15314         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
15315 
15316         synchronized (mLock) {
15317             // We don't expect installation to fail beyond this point
15318             // Add the new setting to mSettings
15319             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
15320             // Add the new setting to mPackages
15321             mPackages.put(pkg.getPackageName(), pkg);
15322             if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
15323                 mApexManager.registerApkInApex(pkg);
15324             }
15325 
15326             // Add the package's KeySets to the global KeySetManagerService
15327             KeySetManagerService ksms = mSettings.getKeySetManagerService();
15328             ksms.addScannedPackageLPw(pkg);
15329 
15330             mComponentResolver.addAllComponents(pkg, chatty);
15331             final boolean isReplace =
15332                     reconciledPkg.prepareResult != null && reconciledPkg.prepareResult.replace;
15333             mAppsFilter.addPackage(pkgSetting, isReplace);
15334             mPackageProperty.addAllProperties(pkg);
15335 
15336             if (oldPkgSetting == null || oldPkgSetting.getPkg() == null) {
15337                 mDomainVerificationManager.addPackage(pkgSetting);
15338             } else {
15339                 mDomainVerificationManager.migrateState(oldPkgSetting, pkgSetting);
15340             }
15341 
15342             int collectionSize = ArrayUtils.size(pkg.getInstrumentations());
15343             StringBuilder r = null;
15344             int i;
15345             for (i = 0; i < collectionSize; i++) {
15346                 ParsedInstrumentation a = pkg.getInstrumentations().get(i);
15347                 a.setPackageName(pkg.getPackageName());
15348                 mInstrumentation.put(a.getComponentName(), a);
15349                 if (chatty) {
15350                     if (r == null) {
15351                         r = new StringBuilder(256);
15352                     } else {
15353                         r.append(' ');
15354                     }
15355                     r.append(a.getName());
15356                 }
15357             }
15358             if (r != null) {
15359                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
15360             }
15361 
15362             final List<String> protectedBroadcasts = pkg.getProtectedBroadcasts();
15363             if (!protectedBroadcasts.isEmpty()) {
15364                 synchronized (mProtectedBroadcasts) {
15365                     mProtectedBroadcasts.addAll(protectedBroadcasts);
15366                 }
15367             }
15368 
15369             mPermissionManager.onPackageAdded(pkg, (scanFlags & SCAN_AS_INSTANT_APP) != 0, oldPkg);
15370         }
15371 
15372         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15373     }
15374 
15375     private void setUpCustomResolverActivity(AndroidPackage pkg, PackageSetting pkgSetting) {
15376         synchronized (mLock) {
15377             mResolverReplaced = true;
15378 
15379             // The instance created in PackageManagerService is special cased to be non-user
15380             // specific, so initialize all the needed fields here.
15381             ApplicationInfo appInfo = pkg.toAppInfoWithoutState();
15382             appInfo.flags = PackageInfoUtils.appInfoFlags(pkg, pkgSetting);
15383             appInfo.privateFlags =
15384                     PackageInfoUtils.appInfoPrivateFlags(pkg, pkgSetting);
15385             appInfo.initForUser(UserHandle.USER_SYSTEM);
15386 
15387             // Set up information for custom user intent resolution activity.
15388             mResolveActivity.applicationInfo = appInfo;
15389             mResolveActivity.name = mCustomResolverComponentName.getClassName();
15390             mResolveActivity.packageName = pkg.getPackageName();
15391             mResolveActivity.processName = pkg.getProcessName();
15392             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
15393             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
15394                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
15395             mResolveActivity.theme = 0;
15396             mResolveActivity.exported = true;
15397             mResolveActivity.enabled = true;
15398             mResolveInfo.activityInfo = mResolveActivity;
15399             mResolveInfo.priority = 0;
15400             mResolveInfo.preferredOrder = 0;
15401             mResolveInfo.match = 0;
15402             mResolveComponentName = mCustomResolverComponentName;
15403             onChanged();
15404             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
15405                     mResolveComponentName);
15406         }
15407     }
15408 
15409     private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
15410         if (installerActivity == null) {
15411             if (DEBUG_INSTANT) {
15412                 Slog.d(TAG, "Clear ephemeral installer activity");
15413             }
15414             mInstantAppInstallerActivity = null;
15415             onChanged();
15416             return;
15417         }
15418 
15419         if (DEBUG_INSTANT) {
15420             Slog.d(TAG, "Set ephemeral installer activity: "
15421                     + installerActivity.getComponentName());
15422         }
15423         // Set up information for ephemeral installer activity
15424         mInstantAppInstallerActivity = installerActivity;
15425         mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
15426                 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
15427         mInstantAppInstallerActivity.exported = true;
15428         mInstantAppInstallerActivity.enabled = true;
15429         mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
15430         mInstantAppInstallerInfo.priority = 1;
15431         mInstantAppInstallerInfo.preferredOrder = 1;
15432         mInstantAppInstallerInfo.isDefault = true;
15433         mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
15434                 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
15435         onChanged();
15436     }
15437 
15438     private void killApplication(String pkgName, @AppIdInt int appId, String reason) {
15439         killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
15440     }
15441 
15442     private void killApplication(String pkgName, @AppIdInt int appId,
15443             @UserIdInt int userId, String reason) {
15444         // Request the ActivityManager to kill the process(only for existing packages)
15445         // so that we do not end up in a confused state while the user is still using the older
15446         // version of the application while the new one gets installed.
15447         final long token = Binder.clearCallingIdentity();
15448         try {
15449             IActivityManager am = ActivityManager.getService();
15450             if (am != null) {
15451                 try {
15452                     am.killApplication(pkgName, appId, userId, reason);
15453                 } catch (RemoteException e) {
15454                 }
15455             }
15456         } finally {
15457             Binder.restoreCallingIdentity(token);
15458         }
15459     }
15460 
15461     private void removePackageLI(AndroidPackage pkg, boolean chatty) {
15462         // Remove the parent package setting
15463         PackageSetting ps = getPackageSetting(pkg.getPackageName());
15464         if (ps != null) {
15465             removePackageLI(ps.name, chatty);
15466         } else if (DEBUG_REMOVE && chatty) {
15467             Log.d(TAG, "Not removing package " + pkg.getPackageName() + "; mExtras == null");
15468         }
15469     }
15470 
15471     private void removePackageLI(String packageName, boolean chatty) {
15472         if (DEBUG_INSTALL) {
15473             if (chatty)
15474                 Log.d(TAG, "Removing package " + packageName);
15475         }
15476 
15477         // writer
15478         synchronized (mLock) {
15479             final AndroidPackage removedPackage = mPackages.remove(packageName);
15480             if (removedPackage != null) {
15481                 cleanPackageDataStructuresLILPw(removedPackage, chatty);
15482             }
15483         }
15484     }
15485 
15486     private void cleanPackageDataStructuresLILPw(AndroidPackage pkg, boolean chatty) {
15487         mComponentResolver.removeAllComponents(pkg, chatty);
15488         mPermissionManager.onPackageRemoved(pkg);
15489         mPackageProperty.removeAllProperties(pkg);
15490 
15491         final int instrumentationSize = ArrayUtils.size(pkg.getInstrumentations());
15492         StringBuilder r = null;
15493         int i;
15494         for (i = 0; i < instrumentationSize; i++) {
15495             ParsedInstrumentation a = pkg.getInstrumentations().get(i);
15496             mInstrumentation.remove(a.getComponentName());
15497             if (DEBUG_REMOVE && chatty) {
15498                 if (r == null) {
15499                     r = new StringBuilder(256);
15500                 } else {
15501                     r.append(' ');
15502                 }
15503                 r.append(a.getName());
15504             }
15505         }
15506         if (r != null) {
15507             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
15508         }
15509 
15510         r = null;
15511         if (pkg.isSystem()) {
15512             // Only system apps can hold shared libraries.
15513             final int libraryNamesSize = pkg.getLibraryNames().size();
15514             for (i = 0; i < libraryNamesSize; i++) {
15515                 String name = pkg.getLibraryNames().get(i);
15516                 if (removeSharedLibraryLPw(name, 0)) {
15517                     if (DEBUG_REMOVE && chatty) {
15518                         if (r == null) {
15519                             r = new StringBuilder(256);
15520                         } else {
15521                             r.append(' ');
15522                         }
15523                         r.append(name);
15524                     }
15525                 }
15526             }
15527         }
15528 
15529         r = null;
15530 
15531         // Any package can hold static shared libraries.
15532         if (pkg.getStaticSharedLibName() != null) {
15533             if (removeSharedLibraryLPw(pkg.getStaticSharedLibName(),
15534                     pkg.getStaticSharedLibVersion())) {
15535                 if (DEBUG_REMOVE && chatty) {
15536                     if (r == null) {
15537                         r = new StringBuilder(256);
15538                     } else {
15539                         r.append(' ');
15540                     }
15541                     r.append(pkg.getStaticSharedLibName());
15542                 }
15543             }
15544         }
15545 
15546         if (r != null) {
15547             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
15548         }
15549     }
15550 
15551     @Override
15552     public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
15553             final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
15554             final int[] userIds, int[] instantUserIds,
15555             @Nullable SparseArray<int[]> broadcastAllowList,
15556             @Nullable Bundle bOptions) {
15557         mHandler.post(() -> {
15558             try {
15559                 final IActivityManager am = ActivityManager.getService();
15560                 if (am == null) return;
15561                 final int[] resolvedUserIds;
15562                 if (userIds == null) {
15563                     resolvedUserIds = am.getRunningUserIds();
15564                 } else {
15565                     resolvedUserIds = userIds;
15566                 }
15567                 doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
15568                         resolvedUserIds, false, broadcastAllowList, bOptions);
15569                 if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
15570                     doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
15571                             instantUserIds, true, null, bOptions);
15572                 }
15573             } catch (RemoteException ex) {
15574             }
15575         });
15576     }
15577 
15578     @Override
15579     public void notifyPackageAdded(String packageName, int uid) {
15580         final PackageListObserver[] observers;
15581         synchronized (mLock) {
15582             if (mPackageListObservers.size() == 0) {
15583                 return;
15584             }
15585             final PackageListObserver[] observerArray =
15586                     new PackageListObserver[mPackageListObservers.size()];
15587             observers = mPackageListObservers.toArray(observerArray);
15588         }
15589         for (int i = observers.length - 1; i >= 0; --i) {
15590             observers[i].onPackageAdded(packageName, uid);
15591         }
15592     }
15593 
15594     @Override
15595     public void notifyPackageChanged(String packageName, int uid) {
15596         final PackageListObserver[] observers;
15597         synchronized (mLock) {
15598             if (mPackageListObservers.size() == 0) {
15599                 return;
15600             }
15601             final PackageListObserver[] observerArray =
15602                     new PackageListObserver[mPackageListObservers.size()];
15603             observers = mPackageListObservers.toArray(observerArray);
15604         }
15605         for (int i = observers.length - 1; i >= 0; --i) {
15606             observers[i].onPackageChanged(packageName, uid);
15607         }
15608     }
15609 
15610     private static final Comparator<ProviderInfo> sProviderInitOrderSorter = (p1, p2) -> {
15611         final int v1 = p1.initOrder;
15612         final int v2 = p2.initOrder;
15613         return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
15614     };
15615 
15616     @Override
notifyPackageRemoved(String packageName, int uid)15617     public void notifyPackageRemoved(String packageName, int uid) {
15618         final PackageListObserver[] observers;
15619         synchronized (mLock) {
15620             if (mPackageListObservers.size() == 0) {
15621                 return;
15622             }
15623             final PackageListObserver[] observerArray =
15624                     new PackageListObserver[mPackageListObservers.size()];
15625             observers = mPackageListObservers.toArray(observerArray);
15626         }
15627         for (int i = observers.length - 1; i >= 0; --i) {
15628             observers[i].onPackageRemoved(packageName, uid);
15629         }
15630     }
15631 
15632     /**
15633      * Sends a broadcast for the given action.
15634      * <p>If {@code isInstantApp} is {@code true}, then the broadcast is protected with
15635      * the {@link android.Manifest.permission#ACCESS_INSTANT_APPS} permission. This allows
15636      * the system and applications allowed to see instant applications to receive package
15637      * lifecycle events for instant applications.
15638      */
doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras, int flags, String targetPkg, IIntentReceiver finishedReceiver, int[] userIds, boolean isInstantApp, @Nullable SparseArray<int[]> broadcastAllowList, @Nullable Bundle bOptions)15639     private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
15640             int flags, String targetPkg, IIntentReceiver finishedReceiver,
15641             int[] userIds, boolean isInstantApp, @Nullable SparseArray<int[]> broadcastAllowList,
15642             @Nullable Bundle bOptions) {
15643         for (int id : userIds) {
15644             final Intent intent = new Intent(action,
15645                     pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
15646             final String[] requiredPermissions =
15647                     isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null;
15648             if (extras != null) {
15649                 intent.putExtras(extras);
15650             }
15651             if (targetPkg != null) {
15652                 intent.setPackage(targetPkg);
15653             }
15654             // Modify the UID when posting to other users
15655             int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
15656             if (uid > 0 && UserHandle.getUserId(uid) != id) {
15657                 uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
15658                 intent.putExtra(Intent.EXTRA_UID, uid);
15659             }
15660             if (broadcastAllowList != null && PLATFORM_PACKAGE_NAME.equals(targetPkg)) {
15661                 intent.putExtra(Intent.EXTRA_VISIBILITY_ALLOW_LIST, broadcastAllowList.get(id));
15662             }
15663             intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
15664             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
15665             if (DEBUG_BROADCASTS) {
15666                 RuntimeException here = new RuntimeException("here");
15667                 here.fillInStackTrace();
15668                 Slog.d(TAG, "Sending to user " + id + ": "
15669                         + intent.toShortString(false, true, false, false)
15670                         + " " + intent.getExtras(), here);
15671             }
15672             mInjector.getLocalService(ActivityManagerInternal.class).broadcastIntent(
15673                     intent, finishedReceiver, requiredPermissions,
15674                     finishedReceiver != null, id,
15675                     broadcastAllowList == null ? null : broadcastAllowList.get(id),
15676                     bOptions);
15677         }
15678     }
15679 
15680     /**
15681      * Check if the external storage media is available. This is true if there
15682      * is a mounted external storage medium or if the external storage is
15683      * emulated.
15684      */
isExternalMediaAvailable()15685     private boolean isExternalMediaAvailable() {
15686         return mMediaMounted || Environment.isExternalStorageEmulated();
15687     }
15688 
15689     /**
15690      * Ensure that the install reason matches what we know about the package installer (e.g. whether
15691      * it is acting on behalf on an enterprise or the user).
15692      *
15693      * Note that the ordering of the conditionals in this method is important. The checks we perform
15694      * are as follows, in this order:
15695      *
15696      * 1) If the install is being performed by a system app, we can trust the app to have set the
15697      *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
15698      *    what it is.
15699      * 2) If the install is being performed by a device or profile owner app, the install reason
15700      *    should be enterprise policy. However, we cannot be sure that the device or profile owner
15701      *    set the install reason correctly. If the app targets an older SDK version where install
15702      *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
15703      *    unset or wrong. Thus, we force the install reason to be enterprise policy.
15704      * 3) In all other cases, the install is being performed by a regular app that is neither part
15705      *    of the system nor a device or profile owner. We have no reason to believe that this app is
15706      *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
15707      *    set to enterprise policy and if so, change it to unknown instead.
15708      */
fixUpInstallReason(String installerPackageName, int installerUid, int installReason)15709     private int fixUpInstallReason(String installerPackageName, int installerUid,
15710             int installReason) {
15711         if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
15712                 == PERMISSION_GRANTED) {
15713             // If the install is being performed by a system app, we trust that app to have set the
15714             // install reason correctly.
15715             return installReason;
15716         }
15717         final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(
15718                 UserHandle.getUserId(installerUid));
15719         if (ownerPackage != null && ownerPackage.equals(installerPackageName)) {
15720             // If the install is being performed by a device or profile owner, the install
15721             // reason should be enterprise policy.
15722             return PackageManager.INSTALL_REASON_POLICY;
15723         }
15724 
15725 
15726         if (installReason == PackageManager.INSTALL_REASON_POLICY) {
15727             // If the install is being performed by a regular app (i.e. neither system app nor
15728             // device or profile owner), we have no reason to believe that the app is acting on
15729             // behalf of an enterprise. If the app set the install reason to enterprise policy,
15730             // change it to unknown instead.
15731             return PackageManager.INSTALL_REASON_UNKNOWN;
15732         }
15733 
15734         // If the install is being performed by a regular app and the install reason was set to any
15735         // value but enterprise policy, leave the install reason unchanged.
15736         return installReason;
15737     }
15738 
installStage(InstallParams params)15739     void installStage(InstallParams params) {
15740         final Message msg = mHandler.obtainMessage(INIT_COPY);
15741         params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
15742         msg.obj = params;
15743 
15744         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
15745                 System.identityHashCode(msg.obj));
15746         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
15747                 System.identityHashCode(msg.obj));
15748 
15749         mHandler.sendMessage(msg);
15750     }
15751 
installStage(InstallParams parent, List<InstallParams> children)15752     void installStage(InstallParams parent, List<InstallParams> children)
15753             throws PackageManagerException {
15754         final Message msg = mHandler.obtainMessage(INIT_COPY);
15755         final MultiPackageInstallParams params =
15756                 new MultiPackageInstallParams(parent, children);
15757         params.setTraceMethod("installStageMultiPackage")
15758                 .setTraceCookie(System.identityHashCode(params));
15759         msg.obj = params;
15760 
15761         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStageMultiPackage",
15762                 System.identityHashCode(msg.obj));
15763         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
15764                 System.identityHashCode(msg.obj));
15765         mHandler.sendMessage(msg);
15766     }
15767 
verifyStage(VerificationParams params)15768     void verifyStage(VerificationParams params) {
15769         mHandler.post(()-> {
15770             params.startCopy();
15771         });
15772     }
15773 
verifyStage(VerificationParams parent, List<VerificationParams> children)15774     void verifyStage(VerificationParams parent, List<VerificationParams> children)
15775             throws PackageManagerException {
15776         final MultiPackageVerificationParams params =
15777                 new MultiPackageVerificationParams(parent, children);
15778         mHandler.post(()-> {
15779             params.startCopy();
15780         });
15781     }
15782 
sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId, int dataLoaderType)15783     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
15784             int userId, int dataLoaderType) {
15785         final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
15786         final boolean isInstantApp = pkgSetting.getInstantApp(userId);
15787         final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
15788         final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
15789         sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
15790                 false /*startReceiver*/, pkgSetting.appId, userIds, instantUserIds,
15791                 dataLoaderType);
15792 
15793         // Send a session commit broadcast
15794         final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
15795         info.installReason = pkgSetting.getInstallReason(userId);
15796         info.appPackageName = packageName;
15797         sendSessionCommitBroadcast(info, userId);
15798     }
15799 
15800     @Override
sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted, boolean includeStopped, @AppIdInt int appId, int[] userIds, int[] instantUserIds, int dataLoaderType)15801     public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
15802             boolean includeStopped, @AppIdInt int appId, int[] userIds, int[] instantUserIds,
15803             int dataLoaderType) {
15804         if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
15805             return;
15806         }
15807         Bundle extras = new Bundle(1);
15808         // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
15809         final int uid = UserHandle.getUid(
15810                 (ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId);
15811         extras.putInt(Intent.EXTRA_UID, uid);
15812         extras.putInt(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType);
15813 
15814         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
15815                 packageName, extras, 0, null, null, userIds, instantUserIds,
15816                 mAppsFilter.getVisibilityAllowList(
15817                         getPackageSettingInternal(packageName, Process.SYSTEM_UID),
15818                         userIds, mSettings.getPackagesLocked()), null);
15819         if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
15820             mHandler.post(() -> {
15821                         for (int userId : userIds) {
15822                             sendBootCompletedBroadcastToSystemApp(
15823                                     packageName, includeStopped, userId);
15824                         }
15825                     }
15826             );
15827         }
15828     }
15829 
15830     /**
15831      * The just-installed/enabled app is bundled on the system, so presumed to be able to run
15832      * automatically without needing an explicit launch.
15833      * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
15834      */
sendBootCompletedBroadcastToSystemApp( String packageName, boolean includeStopped, int userId)15835     private void sendBootCompletedBroadcastToSystemApp(
15836             String packageName, boolean includeStopped, int userId) {
15837         // If user is not running, the app didn't miss any broadcast
15838         if (!mUserManager.isUserRunning(userId)) {
15839             return;
15840         }
15841         final IActivityManager am = ActivityManager.getService();
15842         try {
15843             // Deliver LOCKED_BOOT_COMPLETED first
15844             Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
15845                     .setPackage(packageName);
15846             if (includeStopped) {
15847                 lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
15848             }
15849             final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
15850             final BroadcastOptions bOptions = getTemporaryAppAllowlistBroadcastOptions(
15851                     REASON_LOCKED_BOOT_COMPLETED);
15852             am.broadcastIntentWithFeature(null, null, lockedBcIntent, null, null, 0, null, null,
15853                     requiredPermissions, null, android.app.AppOpsManager.OP_NONE,
15854                     bOptions.toBundle(), false, false, userId);
15855 
15856             // Deliver BOOT_COMPLETED only if user is unlocked
15857             final UserManagerInternal umInternal = mInjector.getUserManagerInternal();
15858             if (umInternal.isUserUnlockingOrUnlocked(userId)) {
15859                 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
15860                 if (includeStopped) {
15861                     bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
15862                 }
15863                 am.broadcastIntentWithFeature(null, null, bcIntent, null, null, 0, null, null,
15864                         requiredPermissions, null, android.app.AppOpsManager.OP_NONE,
15865                         bOptions.toBundle(), false, false, userId);
15866             }
15867         } catch (RemoteException e) {
15868             throw e.rethrowFromSystemServer();
15869         }
15870     }
15871 
15872     @Override
setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId)15873     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
15874             int userId) {
15875         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
15876         PackageSetting pkgSetting;
15877         final int callingUid = Binder.getCallingUid();
15878         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
15879                 true /* checkShell */, "setApplicationHiddenSetting for user " + userId);
15880 
15881         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
15882             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
15883             return false;
15884         }
15885 
15886         final long callingId = Binder.clearCallingIdentity();
15887         try {
15888             boolean sendAdded = false;
15889             boolean sendRemoved = false;
15890             // writer
15891             synchronized (mLock) {
15892                 pkgSetting = mSettings.getPackageLPr(packageName);
15893                 if (pkgSetting == null) {
15894                     return false;
15895                 }
15896                 if (shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
15897                     return false;
15898                 }
15899                 // Do not allow "android" is being disabled
15900                 if ("android".equals(packageName)) {
15901                     Slog.w(TAG, "Cannot hide package: android");
15902                     return false;
15903                 }
15904                 // Cannot hide static shared libs as they are considered
15905                 // a part of the using app (emulating static linking). Also
15906                 // static libs are installed always on internal storage.
15907                 AndroidPackage pkg = mPackages.get(packageName);
15908                 if (pkg != null && pkg.getStaticSharedLibName() != null) {
15909                     Slog.w(TAG, "Cannot hide package: " + packageName
15910                             + " providing static shared library: "
15911                             + pkg.getStaticSharedLibName());
15912                     return false;
15913                 }
15914                 // Only allow protected packages to hide themselves.
15915                 if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
15916                         && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
15917                     Slog.w(TAG, "Not hiding protected package: " + packageName);
15918                     return false;
15919                 }
15920 
15921                 if (pkgSetting.getHidden(userId) != hidden) {
15922                     pkgSetting.setHidden(hidden, userId);
15923                     mSettings.writePackageRestrictionsLPr(userId);
15924                     if (hidden) {
15925                         sendRemoved = true;
15926                     } else {
15927                         sendAdded = true;
15928                     }
15929                 }
15930             }
15931             if (sendAdded) {
15932                 sendPackageAddedForUser(packageName, pkgSetting, userId, DataLoaderType.NONE);
15933                 return true;
15934             }
15935             if (sendRemoved) {
15936                 killApplication(packageName, pkgSetting.appId, userId,
15937                         "hiding pkg");
15938                 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
15939                 return true;
15940             }
15941         } finally {
15942             Binder.restoreCallingIdentity(callingId);
15943         }
15944         return false;
15945     }
15946 
15947     @Override
setSystemAppHiddenUntilInstalled(String packageName, boolean hidden)15948     public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) {
15949         final int callingUid = Binder.getCallingUid();
15950         final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID
15951                 || callingUid == Process.SYSTEM_UID;
15952         if (!calledFromSystemOrPhone) {
15953             mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
15954                     "setSystemAppHiddenUntilInstalled");
15955         }
15956 
15957         synchronized (mLock) {
15958             final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
15959             if (pkgSetting == null || !pkgSetting.isSystem()) {
15960                 return;
15961             }
15962             if (pkgSetting.getPkg().isCoreApp() && !calledFromSystemOrPhone) {
15963                 throw new SecurityException("Only system or phone callers can modify core apps");
15964             }
15965             pkgSetting.getPkgState().setHiddenUntilInstalled(hidden);
15966             final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(packageName);
15967             if (disabledPs == null) {
15968                 return;
15969             }
15970             disabledPs.getPkgState().setHiddenUntilInstalled(hidden);
15971         }
15972     }
15973 
15974     @Override
setSystemAppInstallState(String packageName, boolean installed, int userId)15975     public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
15976         final int callingUid = Binder.getCallingUid();
15977         final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID
15978                 || callingUid == Process.SYSTEM_UID;
15979         if (!calledFromSystemOrPhone) {
15980             mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
15981                     "setSystemAppHiddenUntilInstalled");
15982         }
15983 
15984         synchronized (mLock) {
15985             final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
15986             // The target app should always be in system
15987             if (pkgSetting == null || !pkgSetting.isSystem()) {
15988                 return false;
15989             }
15990             if (pkgSetting.getPkg().isCoreApp() && !calledFromSystemOrPhone) {
15991                 throw new SecurityException("Only system or phone callers can modify core apps");
15992             }
15993             // Check if the install state is the same
15994             if (pkgSetting.getInstalled(userId) == installed) {
15995                 return false;
15996             }
15997         }
15998 
15999         final long callingId = Binder.clearCallingIdentity();
16000         try {
16001             if (installed) {
16002                 // install the app from uninstalled state
16003                 installExistingPackageAsUser(
16004                         packageName,
16005                         userId,
16006                         PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
16007                         PackageManager.INSTALL_REASON_DEVICE_SETUP,
16008                         null);
16009                 return true;
16010             }
16011 
16012             // uninstall the app from installed state
16013             deletePackageVersioned(
16014                     new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
16015                     new LegacyPackageDeleteObserver(null).getBinder(),
16016                     userId,
16017                     PackageManager.DELETE_SYSTEM_APP);
16018             return true;
16019         } finally {
16020             Binder.restoreCallingIdentity(callingId);
16021         }
16022     }
16023 
sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, int userId)16024     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
16025             int userId) {
16026         final PackageRemovedInfo info = new PackageRemovedInfo(this);
16027         info.removedPackage = packageName;
16028         info.installerPackageName = pkgSetting.installSource.installerPackageName;
16029         info.removedUsers = new int[] {userId};
16030         info.broadcastUsers = new int[] {userId};
16031         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
16032         info.sendPackageRemovedBroadcasts(true /*killApp*/, false /*removedBySystem*/);
16033     }
16034 
sendDistractingPackagesChanged(String[] pkgList, int[] uidList, int userId, int distractionFlags)16035     private void sendDistractingPackagesChanged(String[] pkgList, int[] uidList, int userId,
16036             int distractionFlags) {
16037         final Bundle extras = new Bundle(3);
16038         extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
16039         extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
16040         extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags);
16041         sendPackageBroadcast(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null, extras,
16042                 Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, new int[]{userId}, null, null,
16043                 null);
16044     }
16045 
16046     @VisibleForTesting(visibility = Visibility.PRIVATE)
sendPackagesSuspendedForUser(String[] pkgList, int[] uidList, int userId, boolean suspended)16047     void sendPackagesSuspendedForUser(String[] pkgList, int[] uidList, int userId,
16048             boolean suspended) {
16049         final List<List<String>> pkgsToSend = new ArrayList(pkgList.length);
16050         final List<IntArray> uidsToSend = new ArrayList(pkgList.length);
16051         final List<SparseArray<int[]>> allowListsToSend = new ArrayList(pkgList.length);
16052         final int[] userIds = new int[] {userId};
16053         // Get allow lists for the pkg in the pkgList. Merge into the existed pkgs and uids if
16054         // allow lists are the same.
16055         synchronized (mLock) {
16056             for (int i = 0; i < pkgList.length; i++) {
16057                 final String pkgName = pkgList[i];
16058                 final int uid = uidList[i];
16059                 SparseArray<int[]> allowList = mAppsFilter.getVisibilityAllowList(
16060                         getPackageSettingInternal(pkgName, Process.SYSTEM_UID),
16061                         userIds, mSettings.getPackagesLocked());
16062                 if (allowList == null) {
16063                     allowList = new SparseArray<>(0);
16064                 }
16065                 boolean merged = false;
16066                 for (int j = 0; j < allowListsToSend.size(); j++) {
16067                     if (Arrays.equals(allowListsToSend.get(j).get(userId), allowList.get(userId))) {
16068                         pkgsToSend.get(j).add(pkgName);
16069                         uidsToSend.get(j).add(uid);
16070                         merged = true;
16071                         break;
16072                     }
16073                 }
16074                 if (!merged) {
16075                     pkgsToSend.add(new ArrayList<>(Arrays.asList(pkgName)));
16076                     uidsToSend.add(IntArray.wrap(new int[] {uid}));
16077                     allowListsToSend.add(allowList);
16078                 }
16079             }
16080         }
16081 
16082         for (int i = 0; i < pkgsToSend.size(); i++) {
16083             final Bundle extras = new Bundle(3);
16084             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST,
16085                     pkgsToSend.get(i).toArray(new String[pkgsToSend.get(i).size()]));
16086             extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidsToSend.get(i).toArray());
16087             final SparseArray<int[]> allowList = allowListsToSend.get(i).size() == 0
16088                     ? null : allowListsToSend.get(i);
16089             sendPackageBroadcast(
16090                     suspended ? Intent.ACTION_PACKAGES_SUSPENDED
16091                             : Intent.ACTION_PACKAGES_UNSUSPENDED,
16092                     null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
16093                     userIds, null, allowList, null);
16094         }
16095     }
16096 
16097     /**
16098      * Returns true if application is not found or there was an error. Otherwise it returns
16099      * the hidden state of the package for the given user.
16100      */
16101     @Override
getApplicationHiddenSettingAsUser(String packageName, int userId)16102     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
16103         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
16104         final int callingUid = Binder.getCallingUid();
16105         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
16106                 false /* checkShell */, "getApplicationHidden for user " + userId);
16107         PackageSetting ps;
16108         final long callingId = Binder.clearCallingIdentity();
16109         try {
16110             // writer
16111             synchronized (mLock) {
16112                 ps = mSettings.getPackageLPr(packageName);
16113                 if (ps == null) {
16114                     return true;
16115                 }
16116                 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
16117                     return true;
16118                 }
16119                 return ps.getHidden(userId);
16120             }
16121         } finally {
16122             Binder.restoreCallingIdentity(callingId);
16123         }
16124     }
16125 
16126     /**
16127      * @hide
16128      */
16129     @Override
installExistingPackageAsUser(String packageName, int userId, int installFlags, int installReason, List<String> whiteListedPermissions)16130     public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
16131             int installReason, List<String> whiteListedPermissions) {
16132         return installExistingPackageAsUser(packageName, userId, installFlags, installReason,
16133                 whiteListedPermissions, null);
16134     }
16135 
installExistingPackageAsUser(@ullable String packageName, @UserIdInt int userId, @PackageManager.InstallFlags int installFlags, @PackageManager.InstallReason int installReason, @Nullable List<String> allowlistedRestrictedPermissions, @Nullable IntentSender intentSender)16136     int installExistingPackageAsUser(@Nullable String packageName, @UserIdInt int userId,
16137             @PackageManager.InstallFlags int installFlags,
16138             @PackageManager.InstallReason int installReason,
16139             @Nullable List<String> allowlistedRestrictedPermissions,
16140             @Nullable IntentSender intentSender) {
16141         if (DEBUG_INSTALL) {
16142             Log.v(TAG, "installExistingPackageAsUser package=" + packageName + " userId=" + userId
16143                     + " installFlags=" + installFlags + " installReason=" + installReason
16144                     + " allowlistedRestrictedPermissions=" + allowlistedRestrictedPermissions);
16145         }
16146 
16147         final int callingUid = Binder.getCallingUid();
16148         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES)
16149                 != PackageManager.PERMISSION_GRANTED
16150                 && mContext.checkCallingOrSelfPermission(
16151                         android.Manifest.permission.INSTALL_EXISTING_PACKAGES)
16152                 != PackageManager.PERMISSION_GRANTED) {
16153             throw new SecurityException("Neither user " + callingUid + " nor current process has "
16154                     + android.Manifest.permission.INSTALL_PACKAGES + ".");
16155         }
16156         PackageSetting pkgSetting;
16157         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
16158                 true /* checkShell */, "installExistingPackage for user " + userId);
16159         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
16160             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
16161         }
16162 
16163         final long callingId = Binder.clearCallingIdentity();
16164         try {
16165             boolean installed = false;
16166             final boolean instantApp =
16167                     (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16168             final boolean fullApp =
16169                     (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
16170 
16171             // writer
16172             synchronized (mLock) {
16173                 pkgSetting = mSettings.getPackageLPr(packageName);
16174                 if (pkgSetting == null) {
16175                     return PackageManager.INSTALL_FAILED_INVALID_URI;
16176                 }
16177                 if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
16178                     // only allow the existing package to be used if it's installed as a full
16179                     // application for at least one user
16180                     boolean installAllowed = false;
16181                     for (int checkUserId : mUserManager.getUserIds()) {
16182                         installAllowed = !pkgSetting.getInstantApp(checkUserId);
16183                         if (installAllowed) {
16184                             break;
16185                         }
16186                     }
16187                     if (!installAllowed) {
16188                         return PackageManager.INSTALL_FAILED_INVALID_URI;
16189                     }
16190                 }
16191                 if (!pkgSetting.getInstalled(userId)) {
16192                     pkgSetting.setInstalled(true, userId);
16193                     pkgSetting.setHidden(false, userId);
16194                     pkgSetting.setInstallReason(installReason, userId);
16195                     pkgSetting.setUninstallReason(PackageManager.UNINSTALL_REASON_UNKNOWN, userId);
16196                     mSettings.writePackageRestrictionsLPr(userId);
16197                     mSettings.writeKernelMappingLPr(pkgSetting);
16198                     installed = true;
16199                 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
16200                     // upgrade app from instant to full; we don't allow app downgrade
16201                     installed = true;
16202                 }
16203                 setInstantAppForUser(mInjector, pkgSetting, userId, instantApp, fullApp);
16204             }
16205 
16206             if (installed) {
16207                 if (pkgSetting.pkg != null) {
16208                     final PermissionManagerServiceInternal.PackageInstalledParams.Builder
16209                             permissionParamsBuilder =
16210                             new PermissionManagerServiceInternal.PackageInstalledParams.Builder();
16211                     if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS)
16212                             != 0) {
16213                         permissionParamsBuilder.setAllowlistedRestrictedPermissions(
16214                                 pkgSetting.pkg.getRequestedPermissions());
16215                     }
16216                     mPermissionManager.onPackageInstalled(pkgSetting.pkg,
16217                             permissionParamsBuilder.build(), userId);
16218                 }
16219 
16220                 if (pkgSetting.pkg != null) {
16221                     synchronized (mInstallLock) {
16222                         // We don't need to freeze for a brand new install
16223                         prepareAppDataAfterInstallLIF(pkgSetting.pkg);
16224                     }
16225                 }
16226                 sendPackageAddedForUser(packageName, pkgSetting, userId, DataLoaderType.NONE);
16227                 synchronized (mLock) {
16228                     updateSequenceNumberLP(pkgSetting, new int[]{ userId });
16229                 }
16230                 // start async restore with no post-install since we finish install here
16231                 PackageInstalledInfo res =
16232                         createPackageInstalledInfo(PackageManager.INSTALL_SUCCEEDED);
16233                 res.pkg = pkgSetting.pkg;
16234                 res.newUsers = new int[]{ userId };
16235 
16236                 PostInstallData postInstallData =
16237                         new PostInstallData(null, res, () -> {
16238                             restorePermissionsAndUpdateRolesForNewUserInstall(packageName,
16239                                     pkgSetting.getInstallReason(userId), userId);
16240                             if (intentSender != null) {
16241                                 onRestoreComplete(res.returnCode, mContext, intentSender);
16242                             }
16243                         });
16244                 restoreAndPostInstall(userId, res, postInstallData);
16245             }
16246         } finally {
16247             Binder.restoreCallingIdentity(callingId);
16248         }
16249 
16250         return PackageManager.INSTALL_SUCCEEDED;
16251     }
16252 
onRestoreComplete(int returnCode, Context context, IntentSender target)16253     static void onRestoreComplete(int returnCode, Context context, IntentSender target) {
16254         Intent fillIn = new Intent();
16255         fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
16256                 PackageManager.installStatusToPublicStatus(returnCode));
16257         try {
16258             target.sendIntent(context, 0, fillIn, null, null);
16259         } catch (SendIntentException ignored) {
16260         }
16261     }
16262 
setInstantAppForUser(Injector injector, PackageSetting pkgSetting, int userId, boolean instantApp, boolean fullApp)16263     static void setInstantAppForUser(Injector injector, PackageSetting pkgSetting,
16264             int userId, boolean instantApp, boolean fullApp) {
16265         // no state specified; do nothing
16266         if (!instantApp && !fullApp) {
16267             return;
16268         }
16269         if (userId != UserHandle.USER_ALL) {
16270             if (instantApp && !pkgSetting.getInstantApp(userId)) {
16271                 pkgSetting.setInstantApp(true /*instantApp*/, userId);
16272             } else if (fullApp && pkgSetting.getInstantApp(userId)) {
16273                 pkgSetting.setInstantApp(false /*instantApp*/, userId);
16274             }
16275         } else {
16276             for (int currentUserId : injector.getUserManagerInternal().getUserIds()) {
16277                 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
16278                     pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
16279                 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
16280                     pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
16281                 }
16282             }
16283         }
16284     }
16285 
isUserRestricted(int userId, String restrictionKey)16286     boolean isUserRestricted(int userId, String restrictionKey) {
16287         Bundle restrictions = mUserManager.getUserRestrictions(userId);
16288         if (restrictions.getBoolean(restrictionKey, false)) {
16289             Log.w(TAG, "User is restricted: " + restrictionKey);
16290             return true;
16291         }
16292         return false;
16293     }
16294 
16295     @Override
setDistractingPackageRestrictionsAsUser(String[] packageNames, int restrictionFlags, int userId)16296     public String[] setDistractingPackageRestrictionsAsUser(String[] packageNames,
16297             int restrictionFlags, int userId) {
16298         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
16299                 "setDistractingPackageRestrictionsAsUser");
16300 
16301         final int callingUid = Binder.getCallingUid();
16302         if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID
16303                 && UserHandle.getUserId(callingUid) != userId) {
16304             throw new SecurityException("Calling uid " + callingUid + " cannot call for user "
16305                     + userId);
16306         }
16307         Objects.requireNonNull(packageNames, "packageNames cannot be null");
16308         if (restrictionFlags != 0 && !isSuspendAllowedForUser(userId)) {
16309             Slog.w(TAG, "Cannot restrict packages due to restrictions on user " + userId);
16310             return packageNames;
16311         }
16312 
16313         final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
16314         final IntArray changedUids = new IntArray(packageNames.length);
16315         final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
16316         final boolean[] canRestrict = (restrictionFlags != 0) ? canSuspendPackageForUserInternal(
16317                 packageNames, userId) : null;
16318 
16319         for (int i = 0; i < packageNames.length; i++) {
16320             final String packageName = packageNames[i];
16321             final PackageSetting pkgSetting;
16322             synchronized (mLock) {
16323                 pkgSetting = mSettings.getPackageLPr(packageName);
16324                 if (pkgSetting == null
16325                         || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
16326                     Slog.w(TAG, "Could not find package setting for package: " + packageName
16327                             + ". Skipping...");
16328                     unactionedPackages.add(packageName);
16329                     continue;
16330                 }
16331             }
16332             if (canRestrict != null && !canRestrict[i]) {
16333                 unactionedPackages.add(packageName);
16334                 continue;
16335             }
16336             synchronized (mLock) {
16337                 final int oldDistractionFlags = pkgSetting.getDistractionFlags(userId);
16338                 if (restrictionFlags != oldDistractionFlags) {
16339                     pkgSetting.setDistractionFlags(restrictionFlags, userId);
16340                     changedPackagesList.add(packageName);
16341                     changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
16342                 }
16343             }
16344         }
16345 
16346         if (!changedPackagesList.isEmpty()) {
16347             final String[] changedPackages = changedPackagesList.toArray(
16348                     new String[changedPackagesList.size()]);
16349             sendDistractingPackagesChanged(changedPackages, changedUids.toArray(), userId,
16350                     restrictionFlags);
16351             synchronized (mLock) {
16352                 scheduleWritePackageRestrictionsLocked(userId);
16353             }
16354         }
16355         return unactionedPackages.toArray(new String[0]);
16356     }
16357 
enforceCanSetPackagesSuspendedAsUser(String callingPackage, int callingUid, int userId, String callingMethod)16358     private void enforceCanSetPackagesSuspendedAsUser(String callingPackage, int callingUid,
16359             int userId, String callingMethod) {
16360         if (callingUid == Process.ROOT_UID
16361                 // Need to compare app-id to allow system dialogs access on secondary users
16362                 || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
16363             return;
16364         }
16365 
16366         final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
16367         if (ownerPackage != null) {
16368             final int ownerUid = getPackageUid(ownerPackage, 0, userId);
16369             if (ownerUid == callingUid) {
16370                 return;
16371             }
16372         }
16373 
16374         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
16375                 callingMethod);
16376 
16377         final int packageUid = getPackageUid(callingPackage, 0, userId);
16378         final boolean allowedPackageUid = packageUid == callingUid;
16379         // TODO(b/139383163): remove special casing for shell and enforce INTERACT_ACROSS_USERS_FULL
16380         final boolean allowedShell = callingUid == SHELL_UID
16381                 && UserHandle.isSameApp(packageUid, callingUid);
16382 
16383         if (!allowedShell && !allowedPackageUid) {
16384             throw new SecurityException("Calling package " + callingPackage + " in user "
16385                     + userId + " does not belong to calling uid " + callingUid);
16386         }
16387     }
16388 
16389     @Override
setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, PersistableBundle appExtras, PersistableBundle launcherExtras, SuspendDialogInfo dialogInfo, String callingPackage, int userId)16390     public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
16391             PersistableBundle appExtras, PersistableBundle launcherExtras,
16392             SuspendDialogInfo dialogInfo, String callingPackage, int userId) {
16393         final int callingUid = Binder.getCallingUid();
16394         enforceCanSetPackagesSuspendedAsUser(callingPackage, callingUid, userId,
16395                 "setPackagesSuspendedAsUser");
16396 
16397         if (ArrayUtils.isEmpty(packageNames)) {
16398             return packageNames;
16399         }
16400         if (suspended && !isSuspendAllowedForUser(userId)) {
16401             Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId);
16402             return packageNames;
16403         }
16404 
16405         final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
16406         final IntArray changedUids = new IntArray(packageNames.length);
16407         final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
16408         final boolean[] canSuspend = suspended ? canSuspendPackageForUserInternal(packageNames,
16409                 userId) : null;
16410 
16411         for (int i = 0; i < packageNames.length; i++) {
16412             final String packageName = packageNames[i];
16413             if (callingPackage.equals(packageName)) {
16414                 Slog.w(TAG, "Calling package: " + callingPackage + " trying to "
16415                         + (suspended ? "" : "un") + "suspend itself. Ignoring");
16416                 unactionedPackages.add(packageName);
16417                 continue;
16418             }
16419             final PackageSetting pkgSetting;
16420             synchronized (mLock) {
16421                 pkgSetting = mSettings.getPackageLPr(packageName);
16422                 if (pkgSetting == null
16423                         || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
16424                     Slog.w(TAG, "Could not find package setting for package: " + packageName
16425                             + ". Skipping suspending/un-suspending.");
16426                     unactionedPackages.add(packageName);
16427                     continue;
16428                 }
16429             }
16430             if (canSuspend != null && !canSuspend[i]) {
16431                 unactionedPackages.add(packageName);
16432                 continue;
16433             }
16434             boolean packageUnsuspended;
16435             synchronized (mLock) {
16436                 if (suspended) {
16437                     pkgSetting.addOrUpdateSuspension(callingPackage, dialogInfo, appExtras,
16438                             launcherExtras, userId);
16439                 } else {
16440                     pkgSetting.removeSuspension(callingPackage, userId);
16441                 }
16442                 packageUnsuspended = !suspended && !pkgSetting.getSuspended(userId);
16443             }
16444             if (suspended || packageUnsuspended) {
16445                 changedPackagesList.add(packageName);
16446                 changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
16447             }
16448         }
16449 
16450         if (!changedPackagesList.isEmpty()) {
16451             final String[] changedPackages = changedPackagesList.toArray(
16452                     new String[changedPackagesList.size()]);
16453             sendPackagesSuspendedForUser(changedPackages, changedUids.toArray(), userId, suspended);
16454             sendMyPackageSuspendedOrUnsuspended(changedPackages, suspended, userId);
16455             synchronized (mLock) {
16456                 scheduleWritePackageRestrictionsLocked(userId);
16457             }
16458         }
16459         return unactionedPackages.toArray(new String[unactionedPackages.size()]);
16460     }
16461 
16462     @Override
getSuspendedPackageAppExtras(String packageName, int userId)16463     public Bundle getSuspendedPackageAppExtras(String packageName, int userId) {
16464         final int callingUid = Binder.getCallingUid();
16465         if (getPackageUid(packageName, 0, userId) != callingUid) {
16466             throw new SecurityException("Calling package " + packageName
16467                     + " does not belong to calling uid " + callingUid);
16468         }
16469         return getSuspendedPackageAppExtrasInternal(packageName, userId);
16470     }
16471 
getSuspendedPackageAppExtrasInternal(String packageName, int userId)16472     private Bundle getSuspendedPackageAppExtrasInternal(String packageName, int userId) {
16473         synchronized (mLock) {
16474             final PackageSetting ps = mSettings.getPackageLPr(packageName);
16475             if (ps == null) {
16476                 return null;
16477             }
16478             final PackageUserState pus = ps.readUserState(userId);
16479             final Bundle allExtras = new Bundle();
16480             if (pus.suspended) {
16481                 for (int i = 0; i < pus.suspendParams.size(); i++) {
16482                     final PackageUserState.SuspendParams params = pus.suspendParams.valueAt(i);
16483                     if (params != null && params.appExtras != null) {
16484                         allExtras.putAll(params.appExtras);
16485                     }
16486                 }
16487             }
16488             return (allExtras.size() > 0) ? allExtras : null;
16489         }
16490     }
16491 
sendMyPackageSuspendedOrUnsuspended(String[] affectedPackages, boolean suspended, int userId)16492     private void sendMyPackageSuspendedOrUnsuspended(String[] affectedPackages, boolean suspended,
16493             int userId) {
16494         final String action = suspended
16495                 ? Intent.ACTION_MY_PACKAGE_SUSPENDED
16496                 : Intent.ACTION_MY_PACKAGE_UNSUSPENDED;
16497         mHandler.post(() -> {
16498             final IActivityManager am = ActivityManager.getService();
16499             if (am == null) {
16500                 Slog.wtf(TAG, "IActivityManager null. Cannot send MY_PACKAGE_ "
16501                         + (suspended ? "" : "UN") + "SUSPENDED broadcasts");
16502                 return;
16503             }
16504             final int[] targetUserIds = new int[] {userId};
16505             for (String packageName : affectedPackages) {
16506                 final Bundle appExtras = suspended
16507                         ? getSuspendedPackageAppExtrasInternal(packageName, userId)
16508                         : null;
16509                 final Bundle intentExtras;
16510                 if (appExtras != null) {
16511                     intentExtras = new Bundle(1);
16512                     intentExtras.putBundle(Intent.EXTRA_SUSPENDED_PACKAGE_EXTRAS, appExtras);
16513                 } else {
16514                     intentExtras = null;
16515                 }
16516                 doSendBroadcast(am, action, null, intentExtras,
16517                         Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, packageName, null,
16518                         targetUserIds, false, null, null);
16519             }
16520         });
16521     }
16522 
16523     @Override
isPackageSuspendedForUser(String packageName, int userId)16524     public boolean isPackageSuspendedForUser(String packageName, int userId) {
16525         final int callingUid = Binder.getCallingUid();
16526         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
16527                 false /* checkShell */, "isPackageSuspendedForUser for user " + userId);
16528         synchronized (mLock) {
16529             final PackageSetting ps = mSettings.getPackageLPr(packageName);
16530             if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
16531                 throw new IllegalArgumentException("Unknown target package: " + packageName);
16532             }
16533             return ps.getSuspended(userId);
16534         }
16535     }
16536 
unsuspendForSuspendingPackage(String suspendingPackage, int userId)16537     void unsuspendForSuspendingPackage(String suspendingPackage, int userId) {
16538         final String[] allPackages;
16539         synchronized (mLock) {
16540             allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
16541         }
16542         removeSuspensionsBySuspendingPackage(allPackages, suspendingPackage::equals, userId);
16543     }
16544 
isSuspendingAnyPackages(String suspendingPackage, int userId)16545     boolean isSuspendingAnyPackages(String suspendingPackage, int userId) {
16546         synchronized (mLock) {
16547             for (final PackageSetting ps : mSettings.getPackagesLocked().values()) {
16548                 if (ps.isSuspendedBy(suspendingPackage, userId)) {
16549                     return true;
16550                 }
16551             }
16552         }
16553         return false;
16554     }
16555 
16556     /**
16557      * Removes any suspensions on given packages that were added by packages that pass the given
16558      * predicate.
16559      *
16560      * <p> Caller must flush package restrictions if it cares about immediate data consistency.
16561      *
16562      * @param packagesToChange The packages on which the suspension are to be removed.
16563      * @param suspendingPackagePredicate A predicate identifying the suspending packages whose
16564      *                                   suspensions will be removed.
16565      * @param userId The user for which the changes are taking place.
16566      */
removeSuspensionsBySuspendingPackage(String[] packagesToChange, Predicate<String> suspendingPackagePredicate, int userId)16567     void removeSuspensionsBySuspendingPackage(String[] packagesToChange,
16568             Predicate<String> suspendingPackagePredicate, int userId) {
16569         final List<String> unsuspendedPackages = new ArrayList<>();
16570         final IntArray unsuspendedUids = new IntArray();
16571         synchronized (mLock) {
16572             for (String packageName : packagesToChange) {
16573                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
16574                 if (ps != null && ps.getSuspended(userId)) {
16575                     ps.removeSuspension(suspendingPackagePredicate, userId);
16576                     if (!ps.getSuspended(userId)) {
16577                         unsuspendedPackages.add(ps.name);
16578                         unsuspendedUids.add(UserHandle.getUid(userId, ps.getAppId()));
16579                     }
16580                 }
16581             }
16582             scheduleWritePackageRestrictionsLocked(userId);
16583         }
16584         if (!unsuspendedPackages.isEmpty()) {
16585             final String[] packageArray = unsuspendedPackages.toArray(
16586                     new String[unsuspendedPackages.size()]);
16587             sendMyPackageSuspendedOrUnsuspended(packageArray, false, userId);
16588             sendPackagesSuspendedForUser(packageArray, unsuspendedUids.toArray(), userId, false);
16589         }
16590     }
16591 
removeAllDistractingPackageRestrictions(int userId)16592     void removeAllDistractingPackageRestrictions(int userId) {
16593         final String[] allPackages;
16594         synchronized (mLock) {
16595             allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
16596         }
16597         removeDistractingPackageRestrictions(allPackages, userId);
16598     }
16599 
16600     /**
16601      * Removes any {@link android.content.pm.PackageManager.DistractionRestriction restrictions}
16602      * set on given packages.
16603      *
16604      * <p> Caller must flush package restrictions if it cares about immediate data consistency.
16605      *
16606      * @param packagesToChange The packages on which restrictions are to be removed.
16607      * @param userId the user for which changes are taking place.
16608      */
removeDistractingPackageRestrictions(String[] packagesToChange, int userId)16609     void removeDistractingPackageRestrictions(String[] packagesToChange, int userId) {
16610         final List<String> changedPackages = new ArrayList<>();
16611         final IntArray changedUids = new IntArray();
16612         synchronized (mLock) {
16613             for (String packageName : packagesToChange) {
16614                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
16615                 if (ps != null && ps.getDistractionFlags(userId) != 0) {
16616                     ps.setDistractionFlags(0, userId);
16617                     changedPackages.add(ps.name);
16618                     changedUids.add(UserHandle.getUid(userId, ps.getAppId()));
16619                 }
16620             }
16621             if (!changedPackages.isEmpty()) {
16622                 final String[] packageArray = changedPackages.toArray(
16623                         new String[changedPackages.size()]);
16624                 sendDistractingPackagesChanged(packageArray, changedUids.toArray(), userId, 0);
16625                 scheduleWritePackageRestrictionsLocked(userId);
16626             }
16627         }
16628     }
16629 
isCallerDeviceOrProfileOwner(int userId)16630     private boolean isCallerDeviceOrProfileOwner(int userId) {
16631         final int callingUid = Binder.getCallingUid();
16632         if (callingUid == Process.SYSTEM_UID) {
16633             return true;
16634         }
16635         final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
16636         if (ownerPackage != null) {
16637             return callingUid == getPackageUidInternal(ownerPackage, 0, userId, callingUid);
16638         }
16639         return false;
16640     }
16641 
isSuspendAllowedForUser(int userId)16642     private boolean isSuspendAllowedForUser(int userId) {
16643         return isCallerDeviceOrProfileOwner(userId)
16644                 || (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL, userId)
16645                 && !mUserManager.hasUserRestriction(UserManager.DISALLOW_UNINSTALL_APPS, userId));
16646     }
16647 
16648     @Override
getUnsuspendablePackagesForUser(String[] packageNames, int userId)16649     public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) {
16650         Objects.requireNonNull(packageNames, "packageNames cannot be null");
16651         mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
16652                 "getUnsuspendablePackagesForUser");
16653         final int callingUid = Binder.getCallingUid();
16654         if (UserHandle.getUserId(callingUid) != userId) {
16655             throw new SecurityException("Calling uid " + callingUid
16656                     + " cannot query getUnsuspendablePackagesForUser for user " + userId);
16657         }
16658         if (!isSuspendAllowedForUser(userId)) {
16659             Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId);
16660             return packageNames;
16661         }
16662         final ArraySet<String> unactionablePackages = new ArraySet<>();
16663         final boolean[] canSuspend = canSuspendPackageForUserInternal(packageNames, userId);
16664         for (int i = 0; i < packageNames.length; i++) {
16665             if (!canSuspend[i]) {
16666                 unactionablePackages.add(packageNames[i]);
16667                 continue;
16668             }
16669             synchronized (mLock) {
16670                 final PackageSetting ps = mSettings.getPackageLPr(packageNames[i]);
16671                 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
16672                     Slog.w(TAG, "Could not find package setting for package: " + packageNames[i]);
16673                     unactionablePackages.add(packageNames[i]);
16674                 }
16675             }
16676         }
16677         return unactionablePackages.toArray(new String[unactionablePackages.size()]);
16678     }
16679 
16680     /**
16681      * Returns an array of booleans, such that the ith boolean denotes whether the ith package can
16682      * be suspended or not.
16683      *
16684      * @param packageNames  The package names to check suspendability for.
16685      * @param userId The user to check in
16686      * @return An array containing results of the checks
16687      */
16688     @NonNull
canSuspendPackageForUserInternal(@onNull String[] packageNames, int userId)16689     private boolean[] canSuspendPackageForUserInternal(@NonNull String[] packageNames, int userId) {
16690         final boolean[] canSuspend = new boolean[packageNames.length];
16691         final boolean isCallerOwner = isCallerDeviceOrProfileOwner(userId);
16692         final long callingId = Binder.clearCallingIdentity();
16693         try {
16694             final String activeLauncherPackageName = mDefaultAppProvider.getDefaultHome(userId);
16695             final String dialerPackageName = mDefaultAppProvider.getDefaultDialer(userId);
16696             for (int i = 0; i < packageNames.length; i++) {
16697                 canSuspend[i] = false;
16698                 final String packageName = packageNames[i];
16699 
16700                 if (isPackageDeviceAdmin(packageName, userId)) {
16701                     Slog.w(TAG, "Cannot suspend package \"" + packageName
16702                             + "\": has an active device admin");
16703                     continue;
16704                 }
16705                 if (packageName.equals(activeLauncherPackageName)) {
16706                     Slog.w(TAG, "Cannot suspend package \"" + packageName
16707                             + "\": contains the active launcher");
16708                     continue;
16709                 }
16710                 if (packageName.equals(mRequiredInstallerPackage)) {
16711                     Slog.w(TAG, "Cannot suspend package \"" + packageName
16712                             + "\": required for package installation");
16713                     continue;
16714                 }
16715                 if (packageName.equals(mRequiredUninstallerPackage)) {
16716                     Slog.w(TAG, "Cannot suspend package \"" + packageName
16717                             + "\": required for package uninstallation");
16718                     continue;
16719                 }
16720                 if (packageName.equals(mRequiredVerifierPackage)) {
16721                     Slog.w(TAG, "Cannot suspend package \"" + packageName
16722                             + "\": required for package verification");
16723                     continue;
16724                 }
16725                 if (packageName.equals(dialerPackageName)) {
16726                     Slog.w(TAG, "Cannot suspend package \"" + packageName
16727                             + "\": is the default dialer");
16728                     continue;
16729                 }
16730                 if (packageName.equals(mRequiredPermissionControllerPackage)) {
16731                     Slog.w(TAG, "Cannot suspend package \"" + packageName
16732                             + "\": required for permissions management");
16733                     continue;
16734                 }
16735                 synchronized (mLock) {
16736                     if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
16737                         Slog.w(TAG, "Cannot suspend package \"" + packageName
16738                                 + "\": protected package");
16739                         continue;
16740                     }
16741                     if (!isCallerOwner && mSettings.getBlockUninstallLPr(userId, packageName)) {
16742                         Slog.w(TAG, "Cannot suspend package \"" + packageName
16743                                 + "\": blocked by admin");
16744                         continue;
16745                     }
16746 
16747                     // Cannot suspend static shared libs as they are considered
16748                     // a part of the using app (emulating static linking). Also
16749                     // static libs are installed always on internal storage.
16750                     AndroidPackage pkg = mPackages.get(packageName);
16751                     if (pkg != null && pkg.isStaticSharedLibrary()) {
16752                         Slog.w(TAG, "Cannot suspend package: " + packageName
16753                                 + " providing static shared library: "
16754                                 + pkg.getStaticSharedLibName());
16755                         continue;
16756                     }
16757                 }
16758                 if (PLATFORM_PACKAGE_NAME.equals(packageName)) {
16759                     Slog.w(TAG, "Cannot suspend the platform package: " + packageName);
16760                     continue;
16761                 }
16762                 canSuspend[i] = true;
16763             }
16764         } finally {
16765             Binder.restoreCallingIdentity(callingId);
16766         }
16767         return canSuspend;
16768     }
16769 
16770     @Override
verifyPendingInstall(int id, int verificationCode)16771     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
16772         mContext.enforceCallingOrSelfPermission(
16773                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
16774                 "Only package verification agents can verify applications");
16775 
16776         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
16777         final PackageVerificationResponse response = new PackageVerificationResponse(
16778                 verificationCode, Binder.getCallingUid());
16779         msg.arg1 = id;
16780         msg.obj = response;
16781         mHandler.sendMessage(msg);
16782     }
16783 
16784     @Override
extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay)16785     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
16786             long millisecondsToDelay) {
16787         mContext.enforceCallingOrSelfPermission(
16788                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
16789                 "Only package verification agents can extend verification timeouts");
16790 
16791         final PackageVerificationState state = mPendingVerification.get(id);
16792         final PackageVerificationResponse response = new PackageVerificationResponse(
16793                 verificationCodeAtTimeout, Binder.getCallingUid());
16794 
16795         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
16796             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
16797         }
16798         if (millisecondsToDelay < 0) {
16799             millisecondsToDelay = 0;
16800         }
16801         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
16802                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
16803             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
16804         }
16805 
16806         if ((state != null) && !state.timeoutExtended()) {
16807             state.extendTimeout();
16808 
16809             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
16810             msg.arg1 = id;
16811             msg.obj = response;
16812             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
16813         }
16814     }
16815 
broadcastPackageVerified(int verificationId, Uri packageUri, int verificationCode, @Nullable String rootHashString, int dataLoaderType, UserHandle user)16816     private void broadcastPackageVerified(int verificationId, Uri packageUri,
16817             int verificationCode, @Nullable String rootHashString, int dataLoaderType,
16818             UserHandle user) {
16819         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
16820         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
16821         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
16822         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
16823         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
16824         if (rootHashString != null) {
16825             intent.putExtra(PackageManager.EXTRA_VERIFICATION_ROOT_HASH, rootHashString);
16826         }
16827         intent.putExtra(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType);
16828 
16829         mContext.sendBroadcastAsUser(intent, user,
16830                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
16831     }
16832 
matchComponentForVerifier(String packageName, List<ResolveInfo> receivers)16833     private ComponentName matchComponentForVerifier(String packageName,
16834             List<ResolveInfo> receivers) {
16835         ActivityInfo targetReceiver = null;
16836 
16837         final int NR = receivers.size();
16838         for (int i = 0; i < NR; i++) {
16839             final ResolveInfo info = receivers.get(i);
16840             if (info.activityInfo == null) {
16841                 continue;
16842             }
16843 
16844             if (packageName.equals(info.activityInfo.packageName)) {
16845                 targetReceiver = info.activityInfo;
16846                 break;
16847             }
16848         }
16849 
16850         if (targetReceiver == null) {
16851             return null;
16852         }
16853 
16854         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
16855     }
16856 
matchVerifiers(PackageInfoLite pkgInfo, List<ResolveInfo> receivers, final PackageVerificationState verificationState)16857     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
16858             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
16859         if (pkgInfo.verifiers.length == 0) {
16860             return null;
16861         }
16862 
16863         final int N = pkgInfo.verifiers.length;
16864         final List<ComponentName> sufficientVerifiers = new ArrayList<>(N + 1);
16865         for (int i = 0; i < N; i++) {
16866             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
16867 
16868             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
16869                     receivers);
16870             if (comp == null) {
16871                 continue;
16872             }
16873 
16874             final int verifierUid = getUidForVerifier(verifierInfo);
16875             if (verifierUid == -1) {
16876                 continue;
16877             }
16878 
16879             if (DEBUG_VERIFY) {
16880                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
16881                         + " with the correct signature");
16882             }
16883             sufficientVerifiers.add(comp);
16884             verificationState.addSufficientVerifier(verifierUid);
16885         }
16886 
16887         return sufficientVerifiers;
16888     }
16889 
getUidForVerifier(VerifierInfo verifierInfo)16890     private int getUidForVerifier(VerifierInfo verifierInfo) {
16891         synchronized (mLock) {
16892             final AndroidPackage pkg = mPackages.get(verifierInfo.packageName);
16893             if (pkg == null) {
16894                 return -1;
16895             } else if (pkg.getSigningDetails().signatures.length != 1) {
16896                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
16897                         + " has more than one signature; ignoring");
16898                 return -1;
16899             }
16900 
16901             /*
16902              * If the public key of the package's signature does not match
16903              * our expected public key, then this is a different package and
16904              * we should skip.
16905              */
16906 
16907             final byte[] expectedPublicKey;
16908             try {
16909                 final Signature verifierSig = pkg.getSigningDetails().signatures[0];
16910                 final PublicKey publicKey = verifierSig.getPublicKey();
16911                 expectedPublicKey = publicKey.getEncoded();
16912             } catch (CertificateException e) {
16913                 return -1;
16914             }
16915 
16916             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
16917 
16918             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
16919                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
16920                         + " does not have the expected public key; ignoring");
16921                 return -1;
16922             }
16923 
16924             return pkg.getUid();
16925         }
16926     }
16927 
setEnableRollbackCode(int token, int enableRollbackCode)16928     private void setEnableRollbackCode(int token, int enableRollbackCode) {
16929         final Message msg = mHandler.obtainMessage(ENABLE_ROLLBACK_STATUS);
16930         msg.arg1 = token;
16931         msg.arg2 = enableRollbackCode;
16932         mHandler.sendMessage(msg);
16933     }
16934 
16935     @Override
finishPackageInstall(int token, boolean didLaunch)16936     public void finishPackageInstall(int token, boolean didLaunch) {
16937         enforceSystemOrRoot("Only the system is allowed to finish installs");
16938 
16939         if (DEBUG_INSTALL) {
16940             Slog.v(TAG, "BM finishing package install for " + token);
16941         }
16942         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
16943 
16944         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
16945         mHandler.sendMessage(msg);
16946     }
16947 
16948     /**
16949      * Get the verification agent timeout.  Used for both the APK verifier and the
16950      * intent filter verifier.
16951      *
16952      * @return verification timeout in milliseconds
16953      */
getVerificationTimeout()16954     private long getVerificationTimeout() {
16955         long timeout = Global.getLong(mContext.getContentResolver(),
16956                 Global.PACKAGE_VERIFIER_TIMEOUT, DEFAULT_VERIFICATION_TIMEOUT);
16957         // The setting can be used to increase the timeout but not decrease it, since that is
16958         // equivalent to disabling the verifier.
16959         return Math.max(timeout, DEFAULT_VERIFICATION_TIMEOUT);
16960     }
16961 
16962     /**
16963      * Get the integrity verification timeout.
16964      *
16965      * @return verification timeout in milliseconds
16966      */
getIntegrityVerificationTimeout()16967     private long getIntegrityVerificationTimeout() {
16968         long timeout = Global.getLong(mContext.getContentResolver(),
16969                 Global.APP_INTEGRITY_VERIFICATION_TIMEOUT, DEFAULT_INTEGRITY_VERIFICATION_TIMEOUT);
16970         // The setting can be used to increase the timeout but not decrease it, since that is
16971         // equivalent to disabling the integrity component.
16972         return Math.max(timeout, DEFAULT_INTEGRITY_VERIFICATION_TIMEOUT);
16973     }
16974 
16975     /**
16976      * Get the default verification agent response code.
16977      *
16978      * @return default verification response code
16979      */
getDefaultVerificationResponse(UserHandle user)16980     private int getDefaultVerificationResponse(UserHandle user) {
16981         if (mUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
16982             return PackageManager.VERIFICATION_REJECT;
16983         }
16984         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
16985                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
16986                 DEFAULT_VERIFICATION_RESPONSE);
16987     }
16988 
16989     /**
16990      * Get the default integrity verification response code.
16991      */
getDefaultIntegrityVerificationResponse()16992     private int getDefaultIntegrityVerificationResponse() {
16993         // We are not exposing this as a user-configurable setting because we don't want to provide
16994         // an easy way to get around the integrity check.
16995         return PackageManager.VERIFICATION_REJECT;
16996     }
16997 
16998     /**
16999      * Check whether or not package verification has been enabled.
17000      *
17001      * @return true if verification should be performed
17002      */
isVerificationEnabled( PackageInfoLite pkgInfoLite, int userId, int installFlags, int installerUid)17003     private boolean isVerificationEnabled(
17004             PackageInfoLite pkgInfoLite, int userId, int installFlags, int installerUid) {
17005         if (!DEFAULT_VERIFY_ENABLE) {
17006             return false;
17007         }
17008 
17009         // Check if installing from ADB
17010         if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
17011             if (isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS)) {
17012                 return true;
17013             }
17014             // Check if the developer wants to skip verification for ADB installs
17015             if ((installFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0) {
17016                 synchronized (mLock) {
17017                     if (mSettings.getPackageLPr(pkgInfoLite.packageName) == null) {
17018                         // Always verify fresh install
17019                         return true;
17020                     }
17021                 }
17022                 // Only skip when apk is debuggable
17023                 return !pkgInfoLite.debuggable;
17024             }
17025             return Global.getInt(mContext.getContentResolver(),
17026                     Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0;
17027         }
17028 
17029         // only when not installed from ADB, skip verification for instant apps when
17030         // the installer and verifier are the same.
17031         if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
17032             if (mInstantAppInstallerActivity != null
17033                     && mInstantAppInstallerActivity.packageName.equals(
17034                             mRequiredVerifierPackage)) {
17035                 try {
17036                     mInjector.getSystemService(AppOpsManager.class)
17037                             .checkPackage(installerUid, mRequiredVerifierPackage);
17038                     if (DEBUG_VERIFY) {
17039                         Slog.i(TAG, "disable verification for instant app");
17040                     }
17041                     return false;
17042                 } catch (SecurityException ignore) { }
17043             }
17044         }
17045         return true;
17046     }
17047 
17048     /**
17049      * Check whether or not integrity verification has been enabled.
17050      */
isIntegrityVerificationEnabled()17051     private boolean isIntegrityVerificationEnabled() {
17052         // We are not exposing this as a user-configurable setting because we don't want to provide
17053         // an easy way to get around the integrity check.
17054         return DEFAULT_INTEGRITY_VERIFY_ENABLE;
17055     }
17056 
17057     @Deprecated
17058     @Override
verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)17059     public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) {
17060         DomainVerificationProxyV1.queueLegacyVerifyResult(mContext, mDomainVerificationConnection,
17061                 id, verificationCode, failedDomains, Binder.getCallingUid());
17062     }
17063 
17064     @Deprecated
17065     @Override
getIntentVerificationStatus(String packageName, int userId)17066     public int getIntentVerificationStatus(String packageName, int userId) {
17067         return mDomainVerificationManager.getLegacyState(packageName, userId);
17068     }
17069 
17070     @Deprecated
17071     @Override
updateIntentVerificationStatus(String packageName, int status, int userId)17072     public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
17073         return mDomainVerificationManager.setLegacyUserState(packageName, userId, status);
17074     }
17075 
17076     @Deprecated
17077     @Override
getIntentFilterVerifications( String packageName)17078     public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
17079             String packageName) {
17080         return ParceledListSlice.emptyList();
17081     }
17082 
17083     @Override
getAllIntentFilters(String packageName)17084     public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
17085         if (TextUtils.isEmpty(packageName)) {
17086             return ParceledListSlice.emptyList();
17087         }
17088         final int callingUid = Binder.getCallingUid();
17089         final int callingUserId = UserHandle.getUserId(callingUid);
17090         synchronized (mLock) {
17091             AndroidPackage pkg = mPackages.get(packageName);
17092             if (pkg == null || ArrayUtils.isEmpty(pkg.getActivities())) {
17093                 return ParceledListSlice.emptyList();
17094             }
17095             final PackageSetting ps = getPackageSetting(pkg.getPackageName());
17096             if (ps == null) {
17097                 return ParceledListSlice.emptyList();
17098             }
17099             if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
17100                 return ParceledListSlice.emptyList();
17101             }
17102             final int count = ArrayUtils.size(pkg.getActivities());
17103             ArrayList<IntentFilter> result = new ArrayList<>();
17104             for (int n=0; n<count; n++) {
17105                 ParsedActivity activity = pkg.getActivities().get(n);
17106                 if (activity.getIntents() != null && activity.getIntents().size() > 0) {
17107                     result.addAll(activity.getIntents());
17108                 }
17109             }
17110             return new ParceledListSlice<IntentFilter>(result) {
17111                 @Override
17112                 protected void writeElement(IntentFilter parcelable, Parcel dest, int callFlags) {
17113                     parcelable.writeToParcel(dest, callFlags);
17114                 }
17115 
17116                 @Override
17117                 protected void writeParcelableCreator(IntentFilter parcelable, Parcel dest) {
17118                     // All Parcel#writeParcelableCreator does is serialize the class name to
17119                     // access via reflection to grab its CREATOR. This does that manually, pointing
17120                     // to the parent IntentFilter so that all of the subclass fields are ignored.
17121                     dest.writeString(IntentFilter.class.getName());
17122                 }
17123             };
17124         }
17125     }
17126 
17127     /**
17128      * Get the "allow unknown sources" setting.
17129      *
17130      * @return the current "allow unknown sources" setting
17131      */
getUnknownSourcesSettings()17132     private int getUnknownSourcesSettings() {
17133         return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
17134                 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
17135                 -1);
17136     }
17137 
17138     @Override
setInstallerPackageName(String targetPackage, String installerPackageName)17139     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
17140         final int callingUid = Binder.getCallingUid();
17141         final int callingUserId = UserHandle.getUserId(callingUid);
17142         if (getInstantAppPackageName(callingUid) != null) {
17143             return;
17144         }
17145         // writer
17146         synchronized (mLock) {
17147             PackageSetting targetPackageSetting = mSettings.getPackageLPr(targetPackage);
17148             if (targetPackageSetting == null
17149                     || shouldFilterApplicationLocked(
17150                             targetPackageSetting, callingUid, callingUserId)) {
17151                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
17152             }
17153 
17154             PackageSetting installerPackageSetting;
17155             if (installerPackageName != null) {
17156                 installerPackageSetting = mSettings.getPackageLPr(installerPackageName);
17157                 if (installerPackageSetting == null
17158                         || shouldFilterApplicationLocked(
17159                                 installerPackageSetting, callingUid, callingUserId)) {
17160                     throw new IllegalArgumentException("Unknown installer package: "
17161                             + installerPackageName);
17162                 }
17163             } else {
17164                 installerPackageSetting = null;
17165             }
17166 
17167             Signature[] callerSignature;
17168             final int appId = UserHandle.getAppId(callingUid);
17169             final Object obj = mSettings.getSettingLPr(appId);
17170             if (obj != null) {
17171                 if (obj instanceof SharedUserSetting) {
17172                     callerSignature =
17173                             ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
17174                 } else if (obj instanceof PackageSetting) {
17175                     callerSignature = ((PackageSetting)obj).signatures.mSigningDetails.signatures;
17176                 } else {
17177                     throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
17178                 }
17179             } else {
17180                 throw new SecurityException("Unknown calling UID: " + callingUid);
17181             }
17182 
17183             // Verify: can't set installerPackageName to a package that is
17184             // not signed with the same cert as the caller.
17185             if (installerPackageSetting != null) {
17186                 if (compareSignatures(callerSignature,
17187                         installerPackageSetting.signatures.mSigningDetails.signatures)
17188                         != PackageManager.SIGNATURE_MATCH) {
17189                     throw new SecurityException(
17190                             "Caller does not have same cert as new installer package "
17191                             + installerPackageName);
17192                 }
17193             }
17194 
17195             // Verify: if target already has an installer package, it must
17196             // be signed with the same cert as the caller.
17197             String targetInstallerPackageName =
17198                     targetPackageSetting.installSource.installerPackageName;
17199             PackageSetting targetInstallerPkgSetting = targetInstallerPackageName == null ? null :
17200                     mSettings.getPackageLPr(targetInstallerPackageName);
17201 
17202             if (targetInstallerPkgSetting != null) {
17203                 if (compareSignatures(callerSignature,
17204                         targetInstallerPkgSetting.signatures.mSigningDetails.signatures)
17205                         != PackageManager.SIGNATURE_MATCH) {
17206                     throw new SecurityException(
17207                             "Caller does not have same cert as old installer package "
17208                             + targetInstallerPackageName);
17209                 }
17210             } else if (mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES)
17211                     != PackageManager.PERMISSION_GRANTED) {
17212                 // This is probably an attempt to exploit vulnerability b/150857253 of taking
17213                 // privileged installer permissions when the installer has been uninstalled or
17214                 // was never set.
17215                 EventLog.writeEvent(0x534e4554, "150857253", callingUid, "");
17216 
17217                 final long binderToken = Binder.clearCallingIdentity();
17218                 try {
17219                     if (mInjector.getCompatibility().isChangeEnabledByUid(
17220                             THROW_EXCEPTION_ON_REQUIRE_INSTALL_PACKAGES_TO_ADD_INSTALLER_PACKAGE,
17221                             callingUid)) {
17222                         throw new SecurityException("Neither user " + callingUid
17223                                 + " nor current process has "
17224                                 + Manifest.permission.INSTALL_PACKAGES);
17225                     } else {
17226                         // If change disabled, fail silently for backwards compatibility
17227                         return;
17228                     }
17229                 } finally {
17230                     Binder.restoreCallingIdentity(binderToken);
17231                 }
17232             }
17233 
17234             // Okay!
17235             targetPackageSetting.setInstallerPackageName(installerPackageName);
17236             mSettings.addInstallerPackageNames(targetPackageSetting.installSource);
17237             mAppsFilter.addPackage(targetPackageSetting);
17238             scheduleWriteSettingsLocked();
17239         }
17240     }
17241 
17242     @Override
setApplicationCategoryHint(String packageName, int categoryHint, String callerPackageName)17243     public void setApplicationCategoryHint(String packageName, int categoryHint,
17244             String callerPackageName) {
17245         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
17246             throw new SecurityException("Instant applications don't have access to this method");
17247         }
17248         mInjector.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
17249                 callerPackageName);
17250         synchronized (mLock) {
17251             PackageSetting ps = mSettings.getPackageLPr(packageName);
17252             if (ps == null || shouldFilterApplicationLocked(
17253                     ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
17254                 throw new IllegalArgumentException("Unknown target package " + packageName);
17255             }
17256             if (!Objects.equals(callerPackageName, ps.installSource.installerPackageName)) {
17257                 throw new IllegalArgumentException("Calling package " + callerPackageName
17258                         + " is not installer for " + packageName);
17259             }
17260 
17261             if (ps.categoryHint != categoryHint) {
17262                 ps.categoryHint = categoryHint;
17263                 scheduleWriteSettingsLocked();
17264             }
17265         }
17266     }
17267 
17268     // Queue up an async operation since the package installation may take a little while.
processInstallRequestsAsync(boolean success, List<InstallRequest> installRequests)17269     private void processInstallRequestsAsync(boolean success,
17270             List<InstallRequest> installRequests) {
17271         mHandler.post(() -> {
17272             List<InstallRequest> apexInstallRequests = new ArrayList<>();
17273             List<InstallRequest> apkInstallRequests = new ArrayList<>();
17274             for (InstallRequest request : installRequests) {
17275                 if ((request.args.installFlags & PackageManager.INSTALL_APEX) != 0) {
17276                     apexInstallRequests.add(request);
17277                 } else {
17278                     apkInstallRequests.add(request);
17279                 }
17280             }
17281             // Note: supporting multi package install of both APEXes and APKs might requir some
17282             // thinking to ensure atomicity of the install.
17283             if (!apexInstallRequests.isEmpty() && !apkInstallRequests.isEmpty()) {
17284                 // This should've been caught at the validation step, but for some reason wasn't.
17285                 throw new IllegalStateException(
17286                         "Attempted to do a multi package install of both APEXes and APKs");
17287             }
17288             if (!apexInstallRequests.isEmpty()) {
17289                 if (success) {
17290                     // Since installApexPackages requires talking to external service (apexd), we
17291                     // schedule to run it async. Once it finishes, it will resume the install.
17292                     Thread t = new Thread(() -> installApexPackagesTraced(apexInstallRequests),
17293                             "installApexPackages");
17294                     t.start();
17295                 } else {
17296                     // Non-staged APEX installation failed somewhere before
17297                     // processInstallRequestAsync. In that case just notify the observer about the
17298                     // failure.
17299                     InstallRequest request = apexInstallRequests.get(0);
17300                     notifyInstallObserver(request.installResult, request.args.observer);
17301                 }
17302                 return;
17303             }
17304             if (success) {
17305                 for (InstallRequest request : apkInstallRequests) {
17306                     request.args.doPreInstall(request.installResult.returnCode);
17307                 }
17308                 synchronized (mInstallLock) {
17309                     installPackagesTracedLI(apkInstallRequests);
17310                 }
17311                 for (InstallRequest request : apkInstallRequests) {
17312                     request.args.doPostInstall(
17313                             request.installResult.returnCode, request.installResult.uid);
17314                 }
17315             }
17316             for (InstallRequest request : apkInstallRequests) {
17317                 restoreAndPostInstall(request.args.user.getIdentifier(), request.installResult,
17318                         new PostInstallData(request.args, request.installResult, null));
17319             }
17320         });
17321     }
17322 
installApexPackagesTraced(List<InstallRequest> requests)17323     private void installApexPackagesTraced(List<InstallRequest> requests) {
17324         try {
17325             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installApexPackages");
17326             installApexPackages(requests);
17327         } finally {
17328             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17329         }
17330     }
17331 
installApexPackages(List<InstallRequest> requests)17332     private void installApexPackages(List<InstallRequest> requests) {
17333         if (requests.isEmpty()) {
17334             return;
17335         }
17336         if (requests.size() != 1) {
17337             throw new IllegalStateException(
17338                 "Only a non-staged install of a single APEX is supported");
17339         }
17340         InstallRequest request = requests.get(0);
17341         try {
17342             // Should directory scanning logic be moved to ApexManager for better test coverage?
17343             final File dir = request.args.origin.resolvedFile;
17344             final File[] apexes = dir.listFiles();
17345             if (apexes == null) {
17346                 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
17347                         dir.getAbsolutePath() + " is not a directory");
17348             }
17349             if (apexes.length != 1) {
17350                 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
17351                         "Expected exactly one .apex file under " + dir.getAbsolutePath()
17352                                 + " got: " + apexes.length);
17353             }
17354             try (PackageParser2 packageParser = mInjector.getScanningPackageParser()) {
17355                 mApexManager.installPackage(apexes[0], packageParser);
17356             }
17357         } catch (PackageManagerException e) {
17358             request.installResult.setError("APEX installation failed", e);
17359         }
17360         invalidatePackageInfoCache();
17361         notifyInstallObserver(request.installResult, request.args.observer);
17362     }
17363 
createPackageInstalledInfo( int currentStatus)17364     private PackageInstalledInfo createPackageInstalledInfo(
17365             int currentStatus) {
17366         PackageInstalledInfo res = new PackageInstalledInfo();
17367         res.setReturnCode(currentStatus);
17368         res.uid = -1;
17369         res.pkg = null;
17370         res.removedInfo = null;
17371         return res;
17372     }
17373 
17374     /** @param data Post-install is performed only if this is non-null. */
restoreAndPostInstall( int userId, PackageInstalledInfo res, @Nullable PostInstallData data)17375     private void restoreAndPostInstall(
17376             int userId, PackageInstalledInfo res, @Nullable PostInstallData data) {
17377         if (DEBUG_INSTALL) {
17378             Log.v(TAG, "restoreAndPostInstall userId=" + userId + " package=" + res.pkg);
17379         }
17380 
17381         // A restore should be requested at this point if (a) the install
17382         // succeeded, (b) the operation is not an update.
17383         final boolean update = res.removedInfo != null
17384                 && res.removedInfo.removedPackage != null;
17385         boolean doRestore = !update && res.pkg != null;
17386 
17387         // Set up the post-install work request bookkeeping.  This will be used
17388         // and cleaned up by the post-install event handling regardless of whether
17389         // there's a restore pass performed.  Token values are >= 1.
17390         int token;
17391         if (mNextInstallToken < 0) mNextInstallToken = 1;
17392         token = mNextInstallToken++;
17393         if (data != null) {
17394             mRunningInstalls.put(token, data);
17395         } else if (DEBUG_INSTALL) {
17396             Log.v(TAG, "No post-install required for " + token);
17397         }
17398 
17399         if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
17400 
17401         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
17402             // Pass responsibility to the Backup Manager.  It will perform a
17403             // restore if appropriate, then pass responsibility back to the
17404             // Package Manager to run the post-install observer callbacks
17405             // and broadcasts.
17406             if (res.freezer != null) {
17407                 res.freezer.close();
17408             }
17409             doRestore = performBackupManagerRestore(userId, token, res);
17410         }
17411 
17412         // If this is an update to a package that might be potentially downgraded, then we
17413         // need to check with the rollback manager whether there's any userdata that might
17414         // need to be snapshotted or restored for the package.
17415         //
17416         // TODO(narayan): Get this working for cases where userId == UserHandle.USER_ALL.
17417         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && !doRestore && update) {
17418             doRestore = performRollbackManagerRestore(userId, token, res, data);
17419         }
17420 
17421         if (!doRestore) {
17422             // No restore possible, or the Backup Manager was mysteriously not
17423             // available -- just fire the post-install work request directly.
17424             if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
17425 
17426             Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
17427 
17428             Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
17429             mHandler.sendMessage(msg);
17430         }
17431     }
17432 
17433     /**
17434      * Perform Backup Manager restore for a given {@link PackageInstalledInfo}.
17435      * Returns whether the restore successfully completed.
17436      */
performBackupManagerRestore(int userId, int token, PackageInstalledInfo res)17437     private boolean performBackupManagerRestore(int userId, int token, PackageInstalledInfo res) {
17438         IBackupManager bm = IBackupManager.Stub.asInterface(
17439                 ServiceManager.getService(Context.BACKUP_SERVICE));
17440         if (bm != null) {
17441             // For backwards compatibility as USER_ALL previously routed directly to USER_SYSTEM
17442             // in the BackupManager. USER_ALL is used in compatibility tests.
17443             if (userId == UserHandle.USER_ALL) {
17444                 userId = UserHandle.USER_SYSTEM;
17445             }
17446             if (DEBUG_INSTALL) {
17447                 Log.v(TAG, "token " + token + " to BM for possible restore for user " + userId);
17448             }
17449             Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
17450             try {
17451                 if (bm.isUserReadyForBackup(userId)) {
17452                     bm.restoreAtInstallForUser(
17453                             userId, res.pkg.getPackageName(), token);
17454                 } else {
17455                     Slog.w(TAG, "User " + userId + " is not ready. Restore at install "
17456                             + "didn't take place.");
17457                     return false;
17458                 }
17459             } catch (RemoteException e) {
17460                 // can't happen; the backup manager is local
17461             } catch (Exception e) {
17462                 Slog.e(TAG, "Exception trying to enqueue restore", e);
17463                 return false;
17464             }
17465         } else {
17466             Slog.e(TAG, "Backup Manager not found!");
17467             return false;
17468         }
17469         return true;
17470     }
17471 
17472     /**
17473      * Perform Rollback Manager restore for a given {@link PackageInstalledInfo}.
17474      * Returns whether the restore successfully completed.
17475      */
performRollbackManagerRestore(int userId, int token, PackageInstalledInfo res, PostInstallData data)17476     private boolean performRollbackManagerRestore(int userId, int token, PackageInstalledInfo res,
17477             PostInstallData data) {
17478         RollbackManagerInternal rm = mInjector.getLocalService(RollbackManagerInternal.class);
17479 
17480         final String packageName = res.pkg.getPackageName();
17481         final int[] allUsers = mUserManager.getUserIds();
17482         final int[] installedUsers;
17483 
17484         final PackageSetting ps;
17485         int appId = -1;
17486         long ceDataInode = -1;
17487         synchronized (mLock) {
17488             ps = mSettings.getPackageLPr(packageName);
17489             if (ps != null) {
17490                 appId = ps.appId;
17491                 ceDataInode = ps.getCeDataInode(userId);
17492             }
17493 
17494             // NOTE: We ignore the user specified in the InstallParam because we know this is
17495             // an update, and hence need to restore data for all installed users.
17496             installedUsers = ps.queryInstalledUsers(allUsers, true);
17497         }
17498 
17499         boolean doSnapshotOrRestore = data != null && data.args != null
17500                 && ((data.args.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0
17501                 || (data.args.installFlags & PackageManager.INSTALL_REQUEST_DOWNGRADE) != 0);
17502 
17503         if (ps != null && doSnapshotOrRestore) {
17504             final String seInfo = AndroidPackageUtils.getSeInfo(res.pkg, ps);
17505             rm.snapshotAndRestoreUserData(packageName, UserHandle.toUserHandles(installedUsers),
17506                     appId, ceDataInode, seInfo, token);
17507             return true;
17508         }
17509         return false;
17510     }
17511 
17512     /**
17513      * Callback from PackageSettings whenever an app is first transitioned out of the
17514      * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
17515      * the app was "launched" for a restoreAtInstall operation.  Therefore we check
17516      * here whether the app is the target of an ongoing install, and only send the
17517      * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
17518      * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
17519      * handling.
17520      */
notifyFirstLaunch(final String packageName, final String installerPackage, final int userId)17521     void notifyFirstLaunch(final String packageName, final String installerPackage,
17522             final int userId) {
17523         // Serialize this with the rest of the install-process message chain.  In the
17524         // restore-at-install case, this Runnable will necessarily run before the
17525         // POST_INSTALL message is processed, so the contents of mRunningInstalls
17526         // are coherent.  In the non-restore case, the app has already completed install
17527         // and been launched through some other means, so it is not in a problematic
17528         // state for observers to see the FIRST_LAUNCH signal.
17529         mHandler.post(() -> {
17530             for (int i = 0; i < mRunningInstalls.size(); i++) {
17531                 final PostInstallData data = mRunningInstalls.valueAt(i);
17532                 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
17533                     continue;
17534                 }
17535                 if (packageName.equals(data.res.pkg.getPackageName())) {
17536                     // right package; but is it for the right user?
17537                     for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
17538                         if (userId == data.res.newUsers[uIndex]) {
17539                             if (DEBUG_BACKUP) {
17540                                 Slog.i(TAG, "Package " + packageName
17541                                         + " being restored so deferring FIRST_LAUNCH");
17542                             }
17543                             return;
17544                         }
17545                     }
17546                 }
17547             }
17548             // didn't find it, so not being restored
17549             if (DEBUG_BACKUP) {
17550                 Slog.i(TAG, "Package " + packageName + " sending normal FIRST_LAUNCH");
17551             }
17552             final boolean isInstantApp = isInstantApp(packageName, userId);
17553             final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
17554             final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
17555             sendFirstLaunchBroadcast(packageName, installerPackage, userIds, instantUserIds);
17556         });
17557     }
17558 
sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds, int[] instantUserIds)17559     private void sendFirstLaunchBroadcast(String pkgName, String installerPkg,
17560             int[] userIds, int[] instantUserIds) {
17561         sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
17562                 installerPkg, null, userIds, instantUserIds, null /* broadcastAllowList */, null);
17563     }
17564 
17565     private abstract class HandlerParams {
17566         /** User handle for the user requesting the information or installation. */
17567         private final UserHandle mUser;
17568         String traceMethod;
17569         int traceCookie;
17570 
HandlerParams(UserHandle user)17571         HandlerParams(UserHandle user) {
17572             mUser = user;
17573         }
17574 
getUser()17575         UserHandle getUser() {
17576             return mUser;
17577         }
17578 
setTraceMethod(String traceMethod)17579         HandlerParams setTraceMethod(String traceMethod) {
17580             this.traceMethod = traceMethod;
17581             return this;
17582         }
17583 
setTraceCookie(int traceCookie)17584         HandlerParams setTraceCookie(int traceCookie) {
17585             this.traceCookie = traceCookie;
17586             return this;
17587         }
17588 
startCopy()17589         final void startCopy() {
17590             if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
17591             handleStartCopy();
17592             handleReturnCode();
17593         }
17594 
handleStartCopy()17595         abstract void handleStartCopy();
handleReturnCode()17596         abstract void handleReturnCode();
17597     }
17598 
17599     static class OriginInfo {
17600         /**
17601          * Location where install is coming from, before it has been
17602          * copied/renamed into place. This could be a single monolithic APK
17603          * file, or a cluster directory. This location may be untrusted.
17604          */
17605         final File file;
17606 
17607         /**
17608          * Flag indicating that {@link #file} has already been staged, meaning downstream users
17609          * don't need to defensively copy the contents.
17610          */
17611         final boolean staged;
17612 
17613         /**
17614          * Flag indicating that {@link #file} is an already installed app that is being moved.
17615          */
17616         final boolean existing;
17617 
17618         final String resolvedPath;
17619         final File resolvedFile;
17620 
fromNothing()17621         static OriginInfo fromNothing() {
17622             return new OriginInfo(null, false, false);
17623         }
17624 
fromUntrustedFile(File file)17625         static OriginInfo fromUntrustedFile(File file) {
17626             return new OriginInfo(file, false, false);
17627         }
17628 
fromExistingFile(File file)17629         static OriginInfo fromExistingFile(File file) {
17630             return new OriginInfo(file, false, true);
17631         }
17632 
fromStagedFile(File file)17633         static OriginInfo fromStagedFile(File file) {
17634             return new OriginInfo(file, true, false);
17635         }
17636 
OriginInfo(File file, boolean staged, boolean existing)17637         private OriginInfo(File file, boolean staged, boolean existing) {
17638             this.file = file;
17639             this.staged = staged;
17640             this.existing = existing;
17641 
17642             if (file != null) {
17643                 resolvedPath = file.getAbsolutePath();
17644                 resolvedFile = file;
17645             } else {
17646                 resolvedPath = null;
17647                 resolvedFile = null;
17648             }
17649         }
17650     }
17651 
17652     static class MoveInfo {
17653         final int moveId;
17654         final String fromUuid;
17655         final String toUuid;
17656         final String packageName;
17657         final int appId;
17658         final String seinfo;
17659         final int targetSdkVersion;
17660         final String fromCodePath;
17661 
MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, int appId, String seinfo, int targetSdkVersion, String fromCodePath)17662         public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
17663                 int appId, String seinfo, int targetSdkVersion,
17664                 String fromCodePath) {
17665             this.moveId = moveId;
17666             this.fromUuid = fromUuid;
17667             this.toUuid = toUuid;
17668             this.packageName = packageName;
17669             this.appId = appId;
17670             this.seinfo = seinfo;
17671             this.targetSdkVersion = targetSdkVersion;
17672             this.fromCodePath = fromCodePath;
17673         }
17674     }
17675 
17676     static class VerificationInfo {
17677         /** A constant used to indicate that a uid value is not present. */
17678         public static final int NO_UID = -1;
17679 
17680         /** URI referencing where the package was downloaded from. */
17681         final Uri originatingUri;
17682 
17683         /** HTTP referrer URI associated with the originatingURI. */
17684         final Uri referrer;
17685 
17686         /** UID of the application that the install request originated from. */
17687         final int originatingUid;
17688 
17689         /** UID of application requesting the install */
17690         final int installerUid;
17691 
VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid)17692         VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
17693             this.originatingUri = originatingUri;
17694             this.referrer = referrer;
17695             this.originatingUid = originatingUid;
17696             this.installerUid = installerUid;
17697         }
17698     }
17699 
17700     /**
17701      * Container for a multi-package install which refers to all install sessions and args being
17702      * committed together.
17703      */
17704     class MultiPackageInstallParams extends HandlerParams {
17705         private final List<InstallParams> mChildParams;
17706         private final Map<InstallArgs, Integer> mCurrentState;
17707 
MultiPackageInstallParams(InstallParams parent, List<InstallParams> childParams)17708         MultiPackageInstallParams(InstallParams parent, List<InstallParams> childParams)
17709                 throws PackageManagerException {
17710             super(parent.getUser());
17711             if (childParams.size() == 0) {
17712                 throw new PackageManagerException("No child sessions found!");
17713             }
17714             mChildParams = childParams;
17715             for (int i = 0; i < childParams.size(); i++) {
17716                 final InstallParams childParam = childParams.get(i);
17717                 childParam.mParentInstallParams = this;
17718             }
17719             this.mCurrentState = new ArrayMap<>(mChildParams.size());
17720         }
17721 
17722         @Override
handleStartCopy()17723         void handleStartCopy() {
17724             for (InstallParams params : mChildParams) {
17725                 params.handleStartCopy();
17726             }
17727         }
17728 
17729         @Override
handleReturnCode()17730         void handleReturnCode() {
17731             for (InstallParams params : mChildParams) {
17732                 params.handleReturnCode();
17733             }
17734         }
17735 
tryProcessInstallRequest(InstallArgs args, int currentStatus)17736         void tryProcessInstallRequest(InstallArgs args, int currentStatus) {
17737             mCurrentState.put(args, currentStatus);
17738             if (mCurrentState.size() != mChildParams.size()) {
17739                 return;
17740             }
17741             int completeStatus = PackageManager.INSTALL_SUCCEEDED;
17742             for (Integer status : mCurrentState.values()) {
17743                 if (status == PackageManager.INSTALL_UNKNOWN) {
17744                     return;
17745                 } else if (status != PackageManager.INSTALL_SUCCEEDED) {
17746                     completeStatus = status;
17747                     break;
17748                 }
17749             }
17750             final List<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size());
17751             for (Map.Entry<InstallArgs, Integer> entry : mCurrentState.entrySet()) {
17752                 installRequests.add(new InstallRequest(entry.getKey(),
17753                         createPackageInstalledInfo(completeStatus)));
17754             }
17755             processInstallRequestsAsync(
17756                     completeStatus == PackageManager.INSTALL_SUCCEEDED,
17757                     installRequests);
17758         }
17759     }
17760 
17761     class InstallParams extends HandlerParams {
17762         final OriginInfo origin;
17763         final MoveInfo move;
17764         final IPackageInstallObserver2 observer;
17765         int installFlags;
17766         @NonNull final InstallSource installSource;
17767         final String volumeUuid;
17768         int mRet;
17769         final String packageAbiOverride;
17770         final String[] grantedRuntimePermissions;
17771         final List<String> whitelistedRestrictedPermissions;
17772         final int autoRevokePermissionsMode;
17773         final PackageParser.SigningDetails signingDetails;
17774         final int installReason;
17775         final int mInstallScenario;
17776         @Nullable MultiPackageInstallParams mParentInstallParams;
17777         final boolean forceQueryableOverride;
17778         final int mDataLoaderType;
17779         final long requiredInstalledVersionCode;
17780         final PackageLite mPackageLite;
17781 
InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, InstallSource installSource, String volumeUuid, UserHandle user, String packageAbiOverride, PackageLite packageLite)17782         InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
17783                 int installFlags, InstallSource installSource, String volumeUuid,
17784                 UserHandle user, String packageAbiOverride, PackageLite packageLite) {
17785             super(user);
17786             this.origin = origin;
17787             this.move = move;
17788             this.observer = observer;
17789             this.installFlags = installFlags;
17790             this.installSource = Preconditions.checkNotNull(installSource);
17791             this.volumeUuid = volumeUuid;
17792             this.packageAbiOverride = packageAbiOverride;
17793 
17794             this.grantedRuntimePermissions = null;
17795             this.whitelistedRestrictedPermissions = null;
17796             this.autoRevokePermissionsMode = MODE_DEFAULT;
17797             this.signingDetails = PackageParser.SigningDetails.UNKNOWN;
17798             this.installReason = PackageManager.INSTALL_REASON_UNKNOWN;
17799             this.mInstallScenario = PackageManager.INSTALL_SCENARIO_DEFAULT;
17800             this.forceQueryableOverride = false;
17801             this.mDataLoaderType = DataLoaderType.NONE;
17802             this.requiredInstalledVersionCode = PackageManager.VERSION_CODE_HIGHEST;
17803             this.mPackageLite = packageLite;
17804         }
17805 
InstallParams(File stagedDir, IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, InstallSource installSource, UserHandle user, SigningDetails signingDetails, int installerUid, PackageLite packageLite)17806         InstallParams(File stagedDir, IPackageInstallObserver2 observer,
17807                 PackageInstaller.SessionParams sessionParams, InstallSource installSource,
17808                 UserHandle user, SigningDetails signingDetails, int installerUid,
17809                 PackageLite packageLite) {
17810             super(user);
17811             origin = OriginInfo.fromStagedFile(stagedDir);
17812             move = null;
17813             installReason = fixUpInstallReason(
17814                     installSource.installerPackageName, installerUid, sessionParams.installReason);
17815             mInstallScenario = sessionParams.installScenario;
17816             this.observer = observer;
17817             installFlags = sessionParams.installFlags;
17818             this.installSource = installSource;
17819             volumeUuid = sessionParams.volumeUuid;
17820             packageAbiOverride = sessionParams.abiOverride;
17821             grantedRuntimePermissions = sessionParams.grantedRuntimePermissions;
17822             whitelistedRestrictedPermissions = sessionParams.whitelistedRestrictedPermissions;
17823             autoRevokePermissionsMode = sessionParams.autoRevokePermissionsMode;
17824             this.signingDetails = signingDetails;
17825             forceQueryableOverride = sessionParams.forceQueryableOverride;
17826             mDataLoaderType = (sessionParams.dataLoaderParams != null)
17827                     ? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE;
17828             requiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode;
17829             mPackageLite = packageLite;
17830         }
17831 
17832         @Override
toString()17833         public String toString() {
17834             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
17835                     + " file=" + origin.file + "}";
17836         }
17837 
installLocationPolicy(PackageInfoLite pkgLite)17838         private int installLocationPolicy(PackageInfoLite pkgLite) {
17839             String packageName = pkgLite.packageName;
17840             int installLocation = pkgLite.installLocation;
17841             // reader
17842             synchronized (mLock) {
17843                 // Currently installed package which the new package is attempting to replace or
17844                 // null if no such package is installed.
17845                 AndroidPackage installedPkg = mPackages.get(packageName);
17846 
17847                 if (installedPkg != null) {
17848                     if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
17849                         // Check for updated system application.
17850                         if (installedPkg.isSystem()) {
17851                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
17852                         } else {
17853                             // If current upgrade specifies particular preference
17854                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
17855                                 // Application explicitly specified internal.
17856                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
17857                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
17858                                 // App explictly prefers external. Let policy decide
17859                             } else {
17860                                 // Prefer previous location
17861                                 if (installedPkg.isExternalStorage()) {
17862                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
17863                                 }
17864                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
17865                             }
17866                         }
17867                     } else {
17868                         // Invalid install. Return error code
17869                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
17870                     }
17871                 }
17872             }
17873             return pkgLite.recommendedInstallLocation;
17874         }
17875 
17876         /**
17877          * Override install location based on default policy if needed.
17878          *
17879          * Only {@link #installFlags} may mutate in this method.
17880          *
17881          * Only {@link PackageManager#INSTALL_INTERNAL} flag may mutate in
17882          * {@link #installFlags}
17883          */
overrideInstallLocation(PackageInfoLite pkgLite)17884         private int overrideInstallLocation(PackageInfoLite pkgLite) {
17885             final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
17886             if (DEBUG_INSTANT && ephemeral) {
17887                 Slog.v(TAG, "pkgLite for install: " + pkgLite);
17888             }
17889 
17890             if (origin.staged) {
17891                 // If we're already staged, we've firmly committed to an install location
17892                 if (origin.file != null) {
17893                     installFlags |= PackageManager.INSTALL_INTERNAL;
17894                 } else {
17895                     throw new IllegalStateException("Invalid stage location");
17896                 }
17897             } else if (pkgLite.recommendedInstallLocation
17898                     == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
17899                 /*
17900                  * If we are not staged and have too little free space, try to free cache
17901                  * before giving up.
17902                  */
17903                 // TODO: focus freeing disk space on the target device
17904                 final StorageManager storage = StorageManager.from(mContext);
17905                 final long lowThreshold = storage.getStorageLowBytes(
17906                         Environment.getDataDirectory());
17907 
17908                 final long sizeBytes = PackageManagerServiceUtils.calculateInstalledSize(
17909                         origin.resolvedPath, packageAbiOverride);
17910                 if (sizeBytes >= 0) {
17911                     try {
17912                         mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
17913                         pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
17914                                 mPackageLite, origin.resolvedPath, installFlags,
17915                                 packageAbiOverride);
17916                     } catch (InstallerException e) {
17917                         Slog.w(TAG, "Failed to free cache", e);
17918                     }
17919                 }
17920 
17921                 /*
17922                  * The cache free must have deleted the file we downloaded to install.
17923                  *
17924                  * TODO: fix the "freeCache" call to not delete the file we care about.
17925                  */
17926                 if (pkgLite.recommendedInstallLocation
17927                         == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
17928                     pkgLite.recommendedInstallLocation
17929                             = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
17930                 }
17931             }
17932 
17933             int ret = INSTALL_SUCCEEDED;
17934             int loc = pkgLite.recommendedInstallLocation;
17935             if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
17936                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
17937             } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
17938                 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
17939             } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
17940                 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
17941             } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
17942                 ret = PackageManager.INSTALL_FAILED_INVALID_APK;
17943             } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
17944                 ret = PackageManager.INSTALL_FAILED_INVALID_URI;
17945             } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
17946                 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
17947             } else {
17948                 // Override with defaults if needed.
17949                 loc = installLocationPolicy(pkgLite);
17950 
17951                 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
17952 
17953                 if (!onInt) {
17954                     // Override install location with flags
17955                     if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
17956                         // Set the flag to install on external media.
17957                         installFlags &= ~PackageManager.INSTALL_INTERNAL;
17958                     } else {
17959                         // Make sure the flag for installing on external
17960                         // media is unset
17961                         installFlags |= PackageManager.INSTALL_INTERNAL;
17962                     }
17963                 }
17964             }
17965             return ret;
17966         }
17967 
17968         /*
17969          * Invoke remote method to get package information and install
17970          * location values. Override install location based on default
17971          * policy if needed and then create install arguments based
17972          * on the install location.
17973          */
handleStartCopy()17974         public void handleStartCopy() {
17975             if ((installFlags & PackageManager.INSTALL_APEX) != 0) {
17976                 mRet = INSTALL_SUCCEEDED;
17977                 return;
17978             }
17979             PackageInfoLite pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
17980                     mPackageLite, origin.resolvedPath, installFlags, packageAbiOverride);
17981 
17982             // For staged session, there is a delay between its verification and install. Device
17983             // state can change within this delay and hence we need to re-verify certain conditions.
17984             boolean isStaged = (installFlags & INSTALL_STAGED) != 0;
17985             if (isStaged) {
17986                 mRet = verifyReplacingVersionCode(
17987                         pkgLite, requiredInstalledVersionCode, installFlags);
17988                 if (mRet != INSTALL_SUCCEEDED) {
17989                     return;
17990                 }
17991             }
17992 
17993             mRet = overrideInstallLocation(pkgLite);
17994         }
17995 
17996         @Override
handleReturnCode()17997         void handleReturnCode() {
17998             processPendingInstall();
17999         }
18000 
processPendingInstall()18001         private void processPendingInstall() {
18002             InstallArgs args = createInstallArgs(this);
18003             if (mRet == PackageManager.INSTALL_SUCCEEDED) {
18004                 mRet = args.copyApk();
18005             }
18006             if (mRet == PackageManager.INSTALL_SUCCEEDED) {
18007                 F2fsUtils.releaseCompressedBlocks(
18008                         mContext.getContentResolver(), new File(args.getCodePath()));
18009             }
18010             if (mParentInstallParams != null) {
18011                 mParentInstallParams.tryProcessInstallRequest(args, mRet);
18012             } else {
18013                 PackageInstalledInfo res = createPackageInstalledInfo(mRet);
18014                 processInstallRequestsAsync(
18015                         res.returnCode == PackageManager.INSTALL_SUCCEEDED,
18016                         Collections.singletonList(new InstallRequest(args, res)));
18017             }
18018         }
18019     }
18020 
18021     /**
18022      * Container for a multi-package install which refers to all install sessions and args being
18023      * committed together.
18024      */
18025     class MultiPackageVerificationParams extends HandlerParams {
18026         private final IPackageInstallObserver2 mObserver;
18027         private final List<VerificationParams> mChildParams;
18028         private final Map<VerificationParams, Integer> mVerificationState;
18029 
MultiPackageVerificationParams( VerificationParams parent, List<VerificationParams> children)18030         MultiPackageVerificationParams(
18031                 VerificationParams parent,
18032                 List<VerificationParams> children)
18033                 throws PackageManagerException {
18034             super(parent.getUser());
18035             if (children.size() == 0) {
18036                 throw new PackageManagerException("No child sessions found!");
18037             }
18038             mChildParams = children;
18039             // Provide every child with reference to this object as parent
18040             for (int i = 0; i < children.size(); i++) {
18041                 final VerificationParams childParams = children.get(i);
18042                 childParams.mParentVerificationParams = this;
18043             }
18044             this.mVerificationState = new ArrayMap<>(mChildParams.size());
18045             mObserver = parent.observer;
18046         }
18047 
18048         @Override
handleStartCopy()18049         void handleStartCopy() {
18050             for (VerificationParams params : mChildParams) {
18051                 params.handleStartCopy();
18052             }
18053         }
18054 
18055         @Override
handleReturnCode()18056         void handleReturnCode() {
18057             for (VerificationParams params : mChildParams) {
18058                 params.handleReturnCode();
18059             }
18060         }
18061 
trySendVerificationCompleteNotification(VerificationParams child, int currentStatus)18062         void trySendVerificationCompleteNotification(VerificationParams child, int currentStatus) {
18063             mVerificationState.put(child, currentStatus);
18064             if (mVerificationState.size() != mChildParams.size()) {
18065                 return;
18066             }
18067             int completeStatus = PackageManager.INSTALL_SUCCEEDED;
18068             for (Integer status : mVerificationState.values()) {
18069                 if (status == PackageManager.INSTALL_UNKNOWN) {
18070                     return;
18071                 } else if (status != PackageManager.INSTALL_SUCCEEDED) {
18072                     completeStatus = status;
18073                     break;
18074                 }
18075             }
18076             try {
18077                 mObserver.onPackageInstalled(null, completeStatus,
18078                         "Package Verification Result", new Bundle());
18079             } catch (RemoteException e) {
18080                 Slog.i(TAG, "Observer no longer exists.");
18081             }
18082         }
18083     }
18084 
18085     class VerificationParams extends HandlerParams {
18086         final OriginInfo origin;
18087         final IPackageInstallObserver2 observer;
18088         final int installFlags;
18089         @NonNull final InstallSource installSource;
18090         final String packageAbiOverride;
18091         final VerificationInfo verificationInfo;
18092         final PackageParser.SigningDetails signingDetails;
18093         @Nullable MultiPackageVerificationParams mParentVerificationParams;
18094         final long requiredInstalledVersionCode;
18095         final int mDataLoaderType;
18096         final int mSessionId;
18097 
18098         private boolean mWaitForVerificationToComplete;
18099         private boolean mWaitForIntegrityVerificationToComplete;
18100         private boolean mWaitForEnableRollbackToComplete;
18101         private int mRet;
18102 
18103         final PackageLite mPackageLite;
18104 
VerificationParams(UserHandle user, File stagedDir, IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, InstallSource installSource, int installerUid, SigningDetails signingDetails, int sessionId, PackageLite lite)18105         VerificationParams(UserHandle user, File stagedDir, IPackageInstallObserver2 observer,
18106                 PackageInstaller.SessionParams sessionParams, InstallSource installSource,
18107                 int installerUid, SigningDetails signingDetails, int sessionId, PackageLite lite) {
18108             super(user);
18109             origin = OriginInfo.fromStagedFile(stagedDir);
18110             this.observer = observer;
18111             installFlags = sessionParams.installFlags;
18112             this.installSource = installSource;
18113             packageAbiOverride = sessionParams.abiOverride;
18114             verificationInfo = new VerificationInfo(
18115                     sessionParams.originatingUri,
18116                     sessionParams.referrerUri,
18117                     sessionParams.originatingUid,
18118                     installerUid
18119             );
18120             this.signingDetails = signingDetails;
18121             requiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode;
18122             mDataLoaderType = (sessionParams.dataLoaderParams != null)
18123                     ? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE;
18124             mSessionId = sessionId;
18125             mPackageLite = lite;
18126         }
18127 
18128         @Override
toString()18129         public String toString() {
18130             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
18131                     + " file=" + origin.file + "}";
18132         }
18133 
handleStartCopy()18134         public void handleStartCopy() {
18135             if ((installFlags & PackageManager.INSTALL_APEX) != 0) {
18136                 // Apex packages get verified in StagingManager currently.
18137                 // TODO(b/136257624): Move apex verification logic out of StagingManager
18138                 mRet = INSTALL_SUCCEEDED;
18139                 return;
18140             }
18141 
18142             PackageInfoLite pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
18143                     mPackageLite, origin.resolvedPath, installFlags, packageAbiOverride);
18144 
18145             mRet = verifyReplacingVersionCode(pkgLite, requiredInstalledVersionCode, installFlags);
18146             if (mRet != INSTALL_SUCCEEDED) {
18147                 return;
18148             }
18149 
18150             // Perform package verification and enable rollback (unless we are simply moving the
18151             // package).
18152             if (!origin.existing) {
18153                 sendApkVerificationRequest(pkgLite);
18154                 if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
18155                     sendEnableRollbackRequest();
18156                 }
18157             }
18158         }
18159 
sendApkVerificationRequest(PackageInfoLite pkgLite)18160         void sendApkVerificationRequest(PackageInfoLite pkgLite) {
18161             final int verificationId = mPendingVerificationToken++;
18162 
18163             PackageVerificationState verificationState =
18164                     new PackageVerificationState(this);
18165             mPendingVerification.append(verificationId, verificationState);
18166 
18167             sendIntegrityVerificationRequest(verificationId, pkgLite, verificationState);
18168             mRet = sendPackageVerificationRequest(
18169                     verificationId, pkgLite, verificationState);
18170 
18171             // If both verifications are skipped, we should remove the state.
18172             if (verificationState.areAllVerificationsComplete()) {
18173                 mPendingVerification.remove(verificationId);
18174             }
18175         }
18176 
sendEnableRollbackRequest()18177         void sendEnableRollbackRequest() {
18178             final int enableRollbackToken = mPendingEnableRollbackToken++;
18179             Trace.asyncTraceBegin(
18180                     TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
18181             mPendingEnableRollback.append(enableRollbackToken, this);
18182 
18183             Intent enableRollbackIntent = new Intent(Intent.ACTION_PACKAGE_ENABLE_ROLLBACK);
18184             enableRollbackIntent.putExtra(
18185                     PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN,
18186                     enableRollbackToken);
18187             enableRollbackIntent.putExtra(
18188                     PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_SESSION_ID,
18189                     mSessionId);
18190             enableRollbackIntent.setType(PACKAGE_MIME_TYPE);
18191             enableRollbackIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
18192 
18193             // Allow the broadcast to be sent before boot complete.
18194             // This is needed when committing the apk part of a staged
18195             // session in early boot. The rollback manager registers
18196             // its receiver early enough during the boot process that
18197             // it will not miss the broadcast.
18198             enableRollbackIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
18199 
18200             mContext.sendOrderedBroadcastAsUser(enableRollbackIntent, UserHandle.SYSTEM,
18201                     android.Manifest.permission.PACKAGE_ROLLBACK_AGENT,
18202                     new BroadcastReceiver() {
18203                         @Override
18204                         public void onReceive(Context context, Intent intent) {
18205                             // the duration to wait for rollback to be enabled, in millis
18206                             long rollbackTimeout = DeviceConfig.getLong(
18207                                     DeviceConfig.NAMESPACE_ROLLBACK,
18208                                     PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS,
18209                                     DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS);
18210                             if (rollbackTimeout < 0) {
18211                                 rollbackTimeout = DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS;
18212                             }
18213                             final Message msg = mHandler.obtainMessage(
18214                                     ENABLE_ROLLBACK_TIMEOUT);
18215                             msg.arg1 = enableRollbackToken;
18216                             msg.arg2 = mSessionId;
18217                             mHandler.sendMessageDelayed(msg, rollbackTimeout);
18218                         }
18219                     }, null, 0, null, null);
18220 
18221             mWaitForEnableRollbackToComplete = true;
18222         }
18223 
18224         /**
18225          * Send a request to check the integrity of the package.
18226          */
sendIntegrityVerificationRequest( int verificationId, PackageInfoLite pkgLite, PackageVerificationState verificationState)18227         void sendIntegrityVerificationRequest(
18228                 int verificationId,
18229                 PackageInfoLite pkgLite,
18230                 PackageVerificationState verificationState) {
18231             if (!isIntegrityVerificationEnabled()) {
18232                 // Consider the integrity check as passed.
18233                 verificationState.setIntegrityVerificationResult(
18234                         PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
18235                 return;
18236             }
18237 
18238             final Intent integrityVerification =
18239                     new Intent(Intent.ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
18240 
18241             integrityVerification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
18242                     PACKAGE_MIME_TYPE);
18243 
18244             final int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
18245                     | Intent.FLAG_RECEIVER_REGISTERED_ONLY
18246                     | Intent.FLAG_RECEIVER_FOREGROUND;
18247             integrityVerification.addFlags(flags);
18248 
18249             integrityVerification.putExtra(EXTRA_VERIFICATION_ID, verificationId);
18250             integrityVerification.putExtra(EXTRA_PACKAGE_NAME, pkgLite.packageName);
18251             integrityVerification.putExtra(EXTRA_VERSION_CODE, pkgLite.versionCode);
18252             integrityVerification.putExtra(EXTRA_LONG_VERSION_CODE, pkgLite.getLongVersionCode());
18253             populateInstallerExtras(integrityVerification);
18254 
18255             // send to integrity component only.
18256             integrityVerification.setPackage("android");
18257 
18258             final BroadcastOptions options = BroadcastOptions.makeBasic();
18259 
18260             mContext.sendOrderedBroadcastAsUser(integrityVerification, UserHandle.SYSTEM,
18261                     /* receiverPermission= */ null,
18262                     /* appOp= */ AppOpsManager.OP_NONE,
18263                     /* options= */ options.toBundle(),
18264                     new BroadcastReceiver() {
18265                         @Override
18266                         public void onReceive(Context context, Intent intent) {
18267                             final Message msg =
18268                                     mHandler.obtainMessage(CHECK_PENDING_INTEGRITY_VERIFICATION);
18269                             msg.arg1 = verificationId;
18270                             mHandler.sendMessageDelayed(msg, getIntegrityVerificationTimeout());
18271                         }
18272                     }, /* scheduler= */ null,
18273                     /* initialCode= */ 0,
18274                     /* initialData= */ null,
18275                     /* initialExtras= */ null);
18276 
18277             Trace.asyncTraceBegin(
18278                     TRACE_TAG_PACKAGE_MANAGER, "integrity_verification", verificationId);
18279 
18280             // stop the copy until verification succeeds.
18281             mWaitForIntegrityVerificationToComplete = true;
18282         }
18283 
18284         /**
18285          * Send a request to verifier(s) to verify the package if necessary, and return
18286          * {@link PackageManager#INSTALL_SUCCEEDED} if succeeded.
18287          */
sendPackageVerificationRequest( int verificationId, PackageInfoLite pkgLite, PackageVerificationState verificationState)18288         int sendPackageVerificationRequest(
18289                 int verificationId,
18290                 PackageInfoLite pkgLite,
18291                 PackageVerificationState verificationState) {
18292             int ret = INSTALL_SUCCEEDED;
18293 
18294             // TODO: http://b/22976637
18295             // Apps installed for "all" users use the device owner to verify the app
18296             UserHandle verifierUser = getUser();
18297             if (verifierUser == UserHandle.ALL) {
18298                 verifierUser = UserHandle.SYSTEM;
18299             }
18300 
18301             /*
18302              * Determine if we have any installed package verifiers. If we
18303              * do, then we'll defer to them to verify the packages.
18304              */
18305             final int requiredUid = mRequiredVerifierPackage == null ? -1
18306                     : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
18307                             verifierUser.getIdentifier());
18308             verificationState.setRequiredVerifierUid(requiredUid);
18309             final int installerUid =
18310                     verificationInfo == null ? -1 : verificationInfo.installerUid;
18311             final boolean isVerificationEnabled = isVerificationEnabled(
18312                     pkgLite, verifierUser.getIdentifier(), installFlags, installerUid);
18313             final boolean isV4Signed =
18314                     (signingDetails.signatureSchemeVersion == SIGNING_BLOCK_V4);
18315             final boolean isIncrementalInstall =
18316                     (mDataLoaderType == DataLoaderType.INCREMENTAL);
18317             // NOTE: We purposefully skip verification for only incremental installs when there's
18318             // a v4 signature block. Otherwise, proceed with verification as usual.
18319             if (!origin.existing
18320                     && isVerificationEnabled
18321                     && (!isIncrementalInstall || !isV4Signed)) {
18322                 final Intent verification = new Intent(
18323                         Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
18324                 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18325                 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
18326                         PACKAGE_MIME_TYPE);
18327                 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
18328 
18329                 // Query all live verifiers based on current user state
18330                 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
18331                         PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
18332                         false /*allowDynamicSplits*/);
18333 
18334                 if (DEBUG_VERIFY) {
18335                     Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
18336                             + verification.toString() + " with " + pkgLite.verifiers.length
18337                             + " optional verifiers");
18338                 }
18339 
18340                 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
18341 
18342                 verification.putExtra(
18343                         PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, installFlags);
18344 
18345                 verification.putExtra(
18346                         PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, pkgLite.packageName);
18347 
18348                 verification.putExtra(
18349                         PackageManager.EXTRA_VERIFICATION_VERSION_CODE, pkgLite.versionCode);
18350 
18351                 verification.putExtra(
18352                         PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
18353                         pkgLite.getLongVersionCode());
18354 
18355                 populateInstallerExtras(verification);
18356 
18357                 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
18358                         receivers, verificationState);
18359 
18360                 DeviceIdleInternal idleController =
18361                         mInjector.getLocalService(DeviceIdleInternal.class);
18362                 final long idleDuration = getVerificationTimeout();
18363                 final BroadcastOptions options = BroadcastOptions.makeBasic();
18364                 options.setTemporaryAppAllowlist(idleDuration,
18365                         TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
18366                         REASON_PACKAGE_VERIFIER, "");
18367 
18368                 /*
18369                  * If any sufficient verifiers were listed in the package
18370                  * manifest, attempt to ask them.
18371                  */
18372                 if (sufficientVerifiers != null) {
18373                     final int n = sufficientVerifiers.size();
18374                     if (n == 0) {
18375                         Slog.i(TAG, "Additional verifiers required, but none installed.");
18376                         ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
18377                     } else {
18378                         for (int i = 0; i < n; i++) {
18379                             final ComponentName verifierComponent = sufficientVerifiers.get(i);
18380                             idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
18381                                     verifierComponent.getPackageName(), idleDuration,
18382                                     verifierUser.getIdentifier(), false,
18383                                     REASON_PACKAGE_VERIFIER,"package verifier");
18384 
18385                             final Intent sufficientIntent = new Intent(verification);
18386                             sufficientIntent.setComponent(verifierComponent);
18387                             mContext.sendBroadcastAsUser(sufficientIntent, verifierUser,
18388                                     /* receiverPermission= */ null,
18389                                     options.toBundle());
18390                         }
18391                     }
18392                 }
18393 
18394                 if (mRequiredVerifierPackage != null) {
18395                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
18396                             mRequiredVerifierPackage, receivers);
18397                     /*
18398                      * Send the intent to the required verification agent,
18399                      * but only start the verification timeout after the
18400                      * target BroadcastReceivers have run.
18401                      */
18402                     verification.setComponent(requiredVerifierComponent);
18403                     idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
18404                             mRequiredVerifierPackage, idleDuration,
18405                             verifierUser.getIdentifier(), false,
18406                             REASON_PACKAGE_VERIFIER, "package verifier");
18407                     mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
18408                             android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
18409                             /* appOp= */ AppOpsManager.OP_NONE,
18410                             /* options= */ options.toBundle(),
18411                             new BroadcastReceiver() {
18412                                 @Override
18413                                 public void onReceive(Context context, Intent intent) {
18414                                     final Message msg = mHandler
18415                                             .obtainMessage(CHECK_PENDING_VERIFICATION);
18416                                     msg.arg1 = verificationId;
18417                                     mHandler.sendMessageDelayed(msg, getVerificationTimeout());
18418                                 }
18419                             }, null, 0, null, null);
18420 
18421                     Trace.asyncTraceBegin(
18422                             TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
18423 
18424                     /*
18425                      * We don't want the copy to proceed until verification
18426                      * succeeds.
18427                      */
18428                     mWaitForVerificationToComplete = true;
18429                 }
18430             } else {
18431                 verificationState.setVerifierResponse(
18432                         requiredUid, PackageManager.VERIFICATION_ALLOW);
18433             }
18434             return ret;
18435         }
18436 
populateInstallerExtras(Intent intent)18437         void populateInstallerExtras(Intent intent) {
18438             intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
18439                     installSource.initiatingPackageName);
18440 
18441             if (verificationInfo != null) {
18442                 if (verificationInfo.originatingUri != null) {
18443                     intent.putExtra(Intent.EXTRA_ORIGINATING_URI,
18444                             verificationInfo.originatingUri);
18445                 }
18446                 if (verificationInfo.referrer != null) {
18447                     intent.putExtra(Intent.EXTRA_REFERRER,
18448                             verificationInfo.referrer);
18449                 }
18450                 if (verificationInfo.originatingUid >= 0) {
18451                     intent.putExtra(Intent.EXTRA_ORIGINATING_UID,
18452                             verificationInfo.originatingUid);
18453                 }
18454                 if (verificationInfo.installerUid >= 0) {
18455                     intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
18456                             verificationInfo.installerUid);
18457                 }
18458             }
18459         }
18460 
setReturnCode(int ret)18461         void setReturnCode(int ret) {
18462             if (mRet == PackageManager.INSTALL_SUCCEEDED) {
18463                 // Only update mRet if it was previously INSTALL_SUCCEEDED to
18464                 // ensure we do not overwrite any previous failure results.
18465                 mRet = ret;
18466             }
18467         }
18468 
handleVerificationFinished()18469         void handleVerificationFinished() {
18470             mWaitForVerificationToComplete = false;
18471             handleReturnCode();
18472         }
18473 
handleIntegrityVerificationFinished()18474         void handleIntegrityVerificationFinished() {
18475             mWaitForIntegrityVerificationToComplete = false;
18476             handleReturnCode();
18477         }
18478 
18479 
handleRollbackEnabled()18480         void handleRollbackEnabled() {
18481             // TODO(ruhler) b/112431924: Consider halting the install if we
18482             // couldn't enable rollback.
18483             mWaitForEnableRollbackToComplete = false;
18484             handleReturnCode();
18485         }
18486 
18487         @Override
handleReturnCode()18488         void handleReturnCode() {
18489             if (mWaitForVerificationToComplete || mWaitForIntegrityVerificationToComplete
18490                     || mWaitForEnableRollbackToComplete) {
18491                 return;
18492             }
18493             sendVerificationCompleteNotification();
18494         }
18495 
sendVerificationCompleteNotification()18496         private void sendVerificationCompleteNotification() {
18497             if (mParentVerificationParams != null) {
18498                 mParentVerificationParams.trySendVerificationCompleteNotification(this, mRet);
18499             } else {
18500                 try {
18501                     observer.onPackageInstalled(null, mRet, "Package Verification Result",
18502                             new Bundle());
18503                 } catch (RemoteException e) {
18504                     Slog.i(TAG, "Observer no longer exists.");
18505                 }
18506             }
18507         }
18508     }
18509 
createInstallArgs(InstallParams params)18510     private InstallArgs createInstallArgs(InstallParams params) {
18511         if (params.move != null) {
18512             return new MoveInstallArgs(params);
18513         } else {
18514             return new FileInstallArgs(params);
18515         }
18516     }
18517 
18518     /**
18519      * Create args that describe an existing installed package. Typically used
18520      * when cleaning up old installs, or used as a move source.
18521      */
createInstallArgsForExisting(String codePath, String[] instructionSets)18522     private InstallArgs createInstallArgsForExisting(String codePath, String[] instructionSets) {
18523         return new FileInstallArgs(codePath, instructionSets);
18524     }
18525 
18526     static abstract class InstallArgs {
18527         /** @see InstallParams#origin */
18528         final OriginInfo origin;
18529         /** @see InstallParams#move */
18530         final MoveInfo move;
18531 
18532         final IPackageInstallObserver2 observer;
18533         // Always refers to PackageManager flags only
18534         final int installFlags;
18535         @NonNull final InstallSource installSource;
18536         final String volumeUuid;
18537         final UserHandle user;
18538         final String abiOverride;
18539         final String[] installGrantPermissions;
18540         final List<String> whitelistedRestrictedPermissions;
18541         final int autoRevokePermissionsMode;
18542         /** If non-null, drop an async trace when the install completes */
18543         final String traceMethod;
18544         final int traceCookie;
18545         final PackageParser.SigningDetails signingDetails;
18546         final int installReason;
18547         final int mInstallScenario;
18548         final boolean forceQueryableOverride;
18549         final int mDataLoaderType;
18550 
18551         // The list of instruction sets supported by this app. This is currently
18552         // only used during the rmdex() phase to clean up resources. We can get rid of this
18553         // if we move dex files under the common app path.
18554         /* nullable */ String[] instructionSets;
18555 
InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, InstallSource installSource, String volumeUuid, UserHandle user, String[] instructionSets, String abiOverride, String[] installGrantPermissions, List<String> whitelistedRestrictedPermissions, int autoRevokePermissionsMode, String traceMethod, int traceCookie, SigningDetails signingDetails, int installReason, int installScenario, boolean forceQueryableOverride, int dataLoaderType)18556         InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
18557                 int installFlags, InstallSource installSource, String volumeUuid,
18558                 UserHandle user, String[] instructionSets,
18559                 String abiOverride, String[] installGrantPermissions,
18560                 List<String> whitelistedRestrictedPermissions,
18561                 int autoRevokePermissionsMode,
18562                 String traceMethod, int traceCookie, SigningDetails signingDetails,
18563                 int installReason, int installScenario, boolean forceQueryableOverride,
18564                 int dataLoaderType) {
18565             this.origin = origin;
18566             this.move = move;
18567             this.installFlags = installFlags;
18568             this.observer = observer;
18569             this.installSource = Preconditions.checkNotNull(installSource);
18570             this.volumeUuid = volumeUuid;
18571             this.user = user;
18572             this.instructionSets = instructionSets;
18573             this.abiOverride = abiOverride;
18574             this.installGrantPermissions = installGrantPermissions;
18575             this.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
18576             this.autoRevokePermissionsMode = autoRevokePermissionsMode;
18577             this.traceMethod = traceMethod;
18578             this.traceCookie = traceCookie;
18579             this.signingDetails = signingDetails;
18580             this.installReason = installReason;
18581             this.mInstallScenario = installScenario;
18582             this.forceQueryableOverride = forceQueryableOverride;
18583             this.mDataLoaderType = dataLoaderType;
18584         }
18585 
18586         /** New install */
InstallArgs(InstallParams params)18587         InstallArgs(InstallParams params) {
18588             this(params.origin, params.move, params.observer, params.installFlags,
18589                     params.installSource, params.volumeUuid,
18590                     params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
18591                     params.grantedRuntimePermissions, params.whitelistedRestrictedPermissions,
18592                     params.autoRevokePermissionsMode,
18593                     params.traceMethod, params.traceCookie, params.signingDetails,
18594                     params.installReason, params.mInstallScenario, params.forceQueryableOverride,
18595                     params.mDataLoaderType);
18596         }
18597 
copyApk()18598         abstract int copyApk();
doPreInstall(int status)18599         abstract int doPreInstall(int status);
18600 
18601         /**
18602          * Rename package into final resting place. All paths on the given
18603          * scanned package should be updated to reflect the rename.
18604          */
doRename(int status, ParsedPackage parsedPackage)18605         abstract boolean doRename(int status, ParsedPackage parsedPackage);
doPostInstall(int status, int uid)18606         abstract int doPostInstall(int status, int uid);
18607 
18608         /** @see PackageSettingBase#getPath() */
getCodePath()18609         abstract String getCodePath();
18610 
18611         // Need installer lock especially for dex file removal.
cleanUpResourcesLI()18612         abstract void cleanUpResourcesLI();
doPostDeleteLI(boolean delete)18613         abstract boolean doPostDeleteLI(boolean delete);
18614 
18615         /**
18616          * Called before the source arguments are copied. This is used mostly
18617          * for MoveParams when it needs to read the source file to put it in the
18618          * destination.
18619          */
doPreCopy()18620         int doPreCopy() {
18621             return PackageManager.INSTALL_SUCCEEDED;
18622         }
18623 
18624         /**
18625          * Called after the source arguments are copied. This is used mostly for
18626          * MoveParams when it needs to read the source file to put it in the
18627          * destination.
18628          */
doPostCopy(int uid)18629         int doPostCopy(int uid) {
18630             return PackageManager.INSTALL_SUCCEEDED;
18631         }
18632 
isEphemeral()18633         protected boolean isEphemeral() {
18634             return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
18635         }
18636 
getUser()18637         UserHandle getUser() {
18638             return user;
18639         }
18640     }
18641 
removeDexFiles(List<String> allCodePaths, String[] instructionSets)18642     void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
18643         if (!allCodePaths.isEmpty()) {
18644             if (instructionSets == null) {
18645                 throw new IllegalStateException("instructionSet == null");
18646             }
18647             String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
18648             for (String codePath : allCodePaths) {
18649                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
18650                     try {
18651                         mInstaller.rmdex(codePath, dexCodeInstructionSet);
18652                     } catch (InstallerException ignored) {
18653                     }
18654                 }
18655             }
18656         }
18657     }
18658 
18659     /**
18660      * Logic to handle installation of new applications, including copying
18661      * and renaming logic.
18662      */
18663     class FileInstallArgs extends InstallArgs {
18664         private File codeFile;
18665         private File resourceFile;
18666 
18667         // Example topology:
18668         // /data/app/com.example/base.apk
18669         // /data/app/com.example/split_foo.apk
18670         // /data/app/com.example/lib/arm/libfoo.so
18671         // /data/app/com.example/lib/arm64/libfoo.so
18672         // /data/app/com.example/dalvik/arm/base.apk@classes.dex
18673 
18674         /** New install */
FileInstallArgs(InstallParams params)18675         FileInstallArgs(InstallParams params) {
18676             super(params);
18677         }
18678 
18679         /** Existing install */
FileInstallArgs(String codePath, String[] instructionSets)18680         FileInstallArgs(String codePath, String[] instructionSets) {
18681             super(OriginInfo.fromNothing(), null, null, 0, InstallSource.EMPTY,
18682                     null, null, instructionSets, null, null, null, MODE_DEFAULT, null, 0,
18683                     PackageParser.SigningDetails.UNKNOWN,
18684                     PackageManager.INSTALL_REASON_UNKNOWN, PackageManager.INSTALL_SCENARIO_DEFAULT,
18685                     false, DataLoaderType.NONE);
18686             this.codeFile = (codePath != null) ? new File(codePath) : null;
18687         }
18688 
copyApk()18689         int copyApk() {
18690             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
18691             try {
18692                 return doCopyApk();
18693             } finally {
18694                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18695             }
18696         }
18697 
doCopyApk()18698         private int doCopyApk() {
18699             if (origin.staged) {
18700                 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
18701                 codeFile = origin.file;
18702                 return PackageManager.INSTALL_SUCCEEDED;
18703             }
18704 
18705             try {
18706                 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
18707                 final File tempDir =
18708                         mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
18709                 codeFile = tempDir;
18710             } catch (IOException e) {
18711                 Slog.w(TAG, "Failed to create copy file: " + e);
18712                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
18713             }
18714 
18715             int ret = PackageManagerServiceUtils.copyPackage(
18716                     origin.file.getAbsolutePath(), codeFile);
18717             if (ret != PackageManager.INSTALL_SUCCEEDED) {
18718                 Slog.e(TAG, "Failed to copy package");
18719                 return ret;
18720             }
18721 
18722             final boolean isIncremental = isIncrementalPath(codeFile.getAbsolutePath());
18723             final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
18724             NativeLibraryHelper.Handle handle = null;
18725             try {
18726                 handle = NativeLibraryHelper.Handle.create(codeFile);
18727                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
18728                         abiOverride, isIncremental);
18729             } catch (IOException e) {
18730                 Slog.e(TAG, "Copying native libraries failed", e);
18731                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
18732             } finally {
18733                 IoUtils.closeQuietly(handle);
18734             }
18735 
18736             return ret;
18737         }
18738 
doPreInstall(int status)18739         int doPreInstall(int status) {
18740             if (status != PackageManager.INSTALL_SUCCEEDED) {
18741                 cleanUp();
18742             }
18743             return status;
18744         }
18745 
18746         @Override
doRename(int status, ParsedPackage parsedPackage)18747         boolean doRename(int status, ParsedPackage parsedPackage) {
18748             if (status != PackageManager.INSTALL_SUCCEEDED) {
18749                 cleanUp();
18750                 return false;
18751             }
18752 
18753             final File targetDir = resolveTargetDir();
18754             final File beforeCodeFile = codeFile;
18755             final File afterCodeFile = getNextCodePath(targetDir, parsedPackage.getPackageName());
18756 
18757             if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
18758             final boolean onIncremental = mIncrementalManager != null
18759                     && isIncrementalPath(beforeCodeFile.getAbsolutePath());
18760             try {
18761                 makeDirRecursive(afterCodeFile.getParentFile(), 0775);
18762                 if (onIncremental) {
18763                     // Just link files here. The stage dir will be removed when the installation
18764                     // session is completed.
18765                     mIncrementalManager.linkCodePath(beforeCodeFile, afterCodeFile);
18766                 } else {
18767                     Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
18768                 }
18769             } catch (IOException | ErrnoException e) {
18770                 Slog.w(TAG, "Failed to rename", e);
18771                 return false;
18772             }
18773 
18774             if (!onIncremental && !SELinux.restoreconRecursive(afterCodeFile)) {
18775                 Slog.w(TAG, "Failed to restorecon");
18776                 return false;
18777             }
18778 
18779             // Reflect the rename internally
18780             codeFile = afterCodeFile;
18781 
18782             // Reflect the rename in scanned details
18783             try {
18784                 parsedPackage.setCodePath(afterCodeFile.getCanonicalPath());
18785             } catch (IOException e) {
18786                 Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
18787                 return false;
18788             }
18789             parsedPackage.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
18790                     afterCodeFile, parsedPackage.getBaseApkPath()));
18791             parsedPackage.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
18792                     afterCodeFile, parsedPackage.getSplitCodePaths()));
18793 
18794             return true;
18795         }
18796 
18797         // TODO(b/168126411): Once staged install flow starts using the same folder as non-staged
18798         //  flow, we won't need this method anymore.
resolveTargetDir()18799         private File resolveTargetDir() {
18800             boolean isStagedInstall = (installFlags & INSTALL_STAGED) != 0;
18801             if (isStagedInstall) {
18802                 return Environment.getDataAppDirectory(null);
18803             } else {
18804                 return codeFile.getParentFile();
18805             }
18806         }
18807 
doPostInstall(int status, int uid)18808         int doPostInstall(int status, int uid) {
18809             if (status != PackageManager.INSTALL_SUCCEEDED) {
18810                 cleanUp();
18811             }
18812             return status;
18813         }
18814 
18815         @Override
getCodePath()18816         String getCodePath() {
18817             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
18818         }
18819 
cleanUp()18820         private boolean cleanUp() {
18821             if (codeFile == null || !codeFile.exists()) {
18822                 return false;
18823             }
18824             removeCodePathLI(codeFile);
18825             return true;
18826         }
18827 
cleanUpResourcesLI()18828         void cleanUpResourcesLI() {
18829             // Try enumerating all code paths before deleting
18830             List<String> allCodePaths = Collections.EMPTY_LIST;
18831             if (codeFile != null && codeFile.exists()) {
18832                 final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
18833                 final ParseResult<PackageLite> result = ApkLiteParseUtils.parsePackageLite(
18834                         input.reset(), codeFile, /* flags */ 0);
18835                 if (result.isSuccess()) {
18836                     // Ignore error; we tried our best
18837                     allCodePaths = result.getResult().getAllApkPaths();
18838                 }
18839             }
18840 
18841             cleanUp();
18842             removeDexFiles(allCodePaths, instructionSets);
18843         }
18844 
doPostDeleteLI(boolean delete)18845         boolean doPostDeleteLI(boolean delete) {
18846             // XXX err, shouldn't we respect the delete flag?
18847             cleanUpResourcesLI();
18848             return true;
18849         }
18850     }
18851 
18852     /**
18853      * Logic to handle movement of existing installed applications.
18854      */
18855     class MoveInstallArgs extends InstallArgs {
18856         private File codeFile;
18857 
18858         /** New install */
MoveInstallArgs(InstallParams params)18859         MoveInstallArgs(InstallParams params) {
18860             super(params);
18861         }
18862 
copyApk()18863         int copyApk() {
18864             if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
18865                     + move.fromUuid + " to " + move.toUuid);
18866             synchronized (mInstaller) {
18867                 try {
18868                     mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
18869                             move.appId, move.seinfo, move.targetSdkVersion,
18870                             move.fromCodePath);
18871                 } catch (InstallerException e) {
18872                     Slog.w(TAG, "Failed to move app", e);
18873                     return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
18874                 }
18875             }
18876 
18877             final String toPathName = new File(move.fromCodePath).getName();
18878             codeFile = new File(Environment.getDataAppDirectory(move.toUuid), toPathName);
18879             if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
18880 
18881             return PackageManager.INSTALL_SUCCEEDED;
18882         }
18883 
doPreInstall(int status)18884         int doPreInstall(int status) {
18885             if (status != PackageManager.INSTALL_SUCCEEDED) {
18886                 cleanUp(move.toUuid);
18887             }
18888             return status;
18889         }
18890 
18891         @Override
doRename(int status, ParsedPackage parsedPackage)18892         boolean doRename(int status, ParsedPackage parsedPackage) {
18893             if (status != PackageManager.INSTALL_SUCCEEDED) {
18894                 cleanUp(move.toUuid);
18895                 return false;
18896             }
18897 
18898             return true;
18899         }
18900 
doPostInstall(int status, int uid)18901         int doPostInstall(int status, int uid) {
18902             if (status == PackageManager.INSTALL_SUCCEEDED) {
18903                 cleanUp(move.fromUuid);
18904             } else {
18905                 cleanUp(move.toUuid);
18906             }
18907             return status;
18908         }
18909 
18910         @Override
getCodePath()18911         String getCodePath() {
18912             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
18913         }
18914 
cleanUp(String volumeUuid)18915         private boolean cleanUp(String volumeUuid) {
18916             final String toPathName = new File(move.fromCodePath).getName();
18917             final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
18918                     toPathName);
18919             Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
18920             final int[] userIds = mUserManager.getUserIds();
18921             synchronized (mInstallLock) {
18922                 // Clean up both app data and code
18923                 // All package moves are frozen until finished
18924 
18925                 // We purposefully exclude FLAG_STORAGE_EXTERNAL here, since
18926                 // this task was only focused on moving data on internal storage.
18927                 // We don't want ART profiles cleared, because they don't move,
18928                 // so we would be deleting the only copy (b/149200535).
18929                 final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE
18930                         | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES;
18931                 for (int userId : userIds) {
18932                     try {
18933                         mInstaller.destroyAppData(volumeUuid, move.packageName, userId, flags, 0);
18934                     } catch (InstallerException e) {
18935                         Slog.w(TAG, String.valueOf(e));
18936                     }
18937                 }
18938                 removeCodePathLI(codeFile);
18939             }
18940             return true;
18941         }
18942 
cleanUpResourcesLI()18943         void cleanUpResourcesLI() {
18944             throw new UnsupportedOperationException();
18945         }
18946 
doPostDeleteLI(boolean delete)18947         boolean doPostDeleteLI(boolean delete) {
18948             throw new UnsupportedOperationException();
18949         }
18950     }
18951 
18952     /**
18953      * Given {@code targetDir}, returns {@code targetDir/~~[randomStrA]/[packageName]-[randomStrB].}
18954      * Makes sure that {@code targetDir/~~[randomStrA]} directory doesn't exist.
18955      * Notice that this method doesn't actually create any directory.
18956      *
18957      * @param targetDir Directory that is two-levels up from the result directory.
18958      * @param packageName Name of the package whose code files are to be installed under the result
18959      *                    directory.
18960      * @return File object for the directory that should hold the code files of {@code packageName}.
18961      */
getNextCodePath(File targetDir, String packageName)18962     private File getNextCodePath(File targetDir, String packageName) {
18963         SecureRandom random = new SecureRandom();
18964         byte[] bytes = new byte[16];
18965         File firstLevelDir;
18966         do {
18967             random.nextBytes(bytes);
18968             String dirName = RANDOM_DIR_PREFIX
18969                     + Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
18970             firstLevelDir = new File(targetDir, dirName);
18971         } while (firstLevelDir.exists());
18972         random.nextBytes(bytes);
18973         String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
18974         return new File(firstLevelDir, packageName + "-" + suffix);
18975     }
18976 
18977     static class PackageInstalledInfo {
18978         String name;
18979         int uid;
18980         // The set of users that originally had this package installed.
18981         int[] origUsers;
18982         // The set of users that now have this package installed.
18983         int[] newUsers;
18984         AndroidPackage pkg;
18985         int returnCode;
18986         String returnMsg;
18987         String installerPackageName;
18988         PackageRemovedInfo removedInfo;
18989         // The set of packages consuming this shared library or null if no consumers exist.
18990         ArrayList<AndroidPackage> libraryConsumers;
18991         PackageFreezer freezer;
18992 
setError(int code, String msg)18993         public void setError(int code, String msg) {
18994             setReturnCode(code);
18995             setReturnMessage(msg);
18996             Slog.w(TAG, msg);
18997         }
18998 
setError(String msg, PackageParserException e)18999         public void setError(String msg, PackageParserException e) {
19000             setReturnCode(e.error);
19001             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
19002             Slog.w(TAG, msg, e);
19003         }
19004 
setError(String msg, PackageManagerException e)19005         public void setError(String msg, PackageManagerException e) {
19006             returnCode = e.error;
19007             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
19008             Slog.w(TAG, msg, e);
19009         }
19010 
setReturnCode(int returnCode)19011         public void setReturnCode(int returnCode) {
19012             this.returnCode = returnCode;
19013         }
19014 
setReturnMessage(String returnMsg)19015         private void setReturnMessage(String returnMsg) {
19016             this.returnMsg = returnMsg;
19017         }
19018 
19019         // In some error cases we want to convey more info back to the observer
19020         String origPackage;
19021         String origPermission;
19022     }
19023 
updateDigest(MessageDigest digest, File file)19024     private static void updateDigest(MessageDigest digest, File file) throws IOException {
19025         try (DigestInputStream digestStream =
19026                 new DigestInputStream(new FileInputStream(file), digest)) {
19027             while (digestStream.read() != -1) {} // nothing to do; just plow through the file
19028         }
19029     }
19030 
removeNativeBinariesLI(PackageSetting ps)19031     private void removeNativeBinariesLI(PackageSetting ps) {
19032         if (ps != null) {
19033             NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
19034         }
19035     }
19036 
19037     @GuardedBy("mLock")
enableSystemPackageLPw(AndroidPackage pkg)19038     private void enableSystemPackageLPw(AndroidPackage pkg) {
19039         mSettings.enableSystemPackageLPw(pkg.getPackageName());
19040     }
19041 
19042     @GuardedBy("mLock")
disableSystemPackageLPw(AndroidPackage oldPkg)19043     private boolean disableSystemPackageLPw(AndroidPackage oldPkg) {
19044         return mSettings.disableSystemPackageLPw(oldPkg.getPackageName(), true);
19045     }
19046 
updateSettingsLI(AndroidPackage newPackage, InstallArgs installArgs, int[] allUsers, PackageInstalledInfo res)19047     private void updateSettingsLI(AndroidPackage newPackage, InstallArgs installArgs,
19048             int[] allUsers, PackageInstalledInfo res) {
19049         updateSettingsInternalLI(newPackage, installArgs, allUsers, res);
19050     }
19051 
updateSettingsInternalLI(AndroidPackage pkg, InstallArgs installArgs, int[] allUsers, PackageInstalledInfo res)19052     private void updateSettingsInternalLI(AndroidPackage pkg, InstallArgs installArgs,
19053             int[] allUsers, PackageInstalledInfo res) {
19054         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
19055 
19056         final String pkgName = pkg.getPackageName();
19057         final int[] installedForUsers = res.origUsers;
19058         final int installReason = installArgs.installReason;
19059         InstallSource installSource = installArgs.installSource;
19060         final String installerPackageName = installSource.installerPackageName;
19061 
19062         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.getPath());
19063         synchronized (mLock) {
19064             // For system-bundled packages, we assume that installing an upgraded version
19065             // of the package implies that the user actually wants to run that new code,
19066             // so we enable the package.
19067             final PackageSetting ps = mSettings.getPackageLPr(pkgName);
19068             final int userId = installArgs.user.getIdentifier();
19069             if (ps != null) {
19070                 if (pkg.isSystem()) {
19071                     if (DEBUG_INSTALL) {
19072                         Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
19073                     }
19074                     // Enable system package for requested users
19075                     if (res.origUsers != null) {
19076                         for (int origUserId : res.origUsers) {
19077                             if (userId == UserHandle.USER_ALL || userId == origUserId) {
19078                                 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
19079                                         origUserId, installerPackageName);
19080                             }
19081                         }
19082                     }
19083                     // Also convey the prior install/uninstall state
19084                     if (allUsers != null && installedForUsers != null) {
19085                         for (int currentUserId : allUsers) {
19086                             final boolean installed = ArrayUtils.contains(
19087                                     installedForUsers, currentUserId);
19088                             if (DEBUG_INSTALL) {
19089                                 Slog.d(TAG, "    user " + currentUserId + " => " + installed);
19090                             }
19091                             ps.setInstalled(installed, currentUserId);
19092                         }
19093                         // these install state changes will be persisted in the
19094                         // upcoming call to mSettings.writeLPr().
19095                     }
19096 
19097                     if (allUsers != null) {
19098                         for (int currentUserId : allUsers) {
19099                             ps.resetOverrideComponentLabelIcon(currentUserId);
19100                         }
19101                     }
19102                 }
19103 
19104                 // Retrieve the overlays for shared libraries of the package.
19105                 if (!ps.getPkgState().getUsesLibraryInfos().isEmpty()) {
19106                     for (SharedLibraryInfo sharedLib : ps.getPkgState().getUsesLibraryInfos()) {
19107                         for (int currentUserId : UserManagerService.getInstance().getUserIds()) {
19108                             if (!sharedLib.isDynamic()) {
19109                                 // TODO(146804378): Support overlaying static shared libraries
19110                                 continue;
19111                             }
19112                             final PackageSetting libPs = mSettings.getPackageLPr(
19113                                     sharedLib.getPackageName());
19114                             if (libPs == null) {
19115                                 continue;
19116                             }
19117                             ps.setOverlayPathsForLibrary(sharedLib.getName(),
19118                                     libPs.getOverlayPaths(currentUserId), currentUserId);
19119                         }
19120                     }
19121                 }
19122 
19123                 // It's implied that when a user requests installation, they want the app to be
19124                 // installed and enabled. (This does not apply to USER_ALL, which here means only
19125                 // install on users for which the app is already installed).
19126                 if (userId != UserHandle.USER_ALL) {
19127                     ps.setInstalled(true, userId);
19128                     ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
19129                 }
19130 
19131                 mSettings.addInstallerPackageNames(ps.installSource);
19132 
19133                 // When replacing an existing package, preserve the original install reason for all
19134                 // users that had the package installed before. Similarly for uninstall reasons.
19135                 final Set<Integer> previousUserIds = new ArraySet<>();
19136                 if (res.removedInfo != null && res.removedInfo.installReasons != null) {
19137                     final int installReasonCount = res.removedInfo.installReasons.size();
19138                     for (int i = 0; i < installReasonCount; i++) {
19139                         final int previousUserId = res.removedInfo.installReasons.keyAt(i);
19140                         final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
19141                         ps.setInstallReason(previousInstallReason, previousUserId);
19142                         previousUserIds.add(previousUserId);
19143                     }
19144                 }
19145                 if (res.removedInfo != null && res.removedInfo.uninstallReasons != null) {
19146                     for (int i = 0; i < res.removedInfo.uninstallReasons.size(); i++) {
19147                         final int previousUserId = res.removedInfo.uninstallReasons.keyAt(i);
19148                         final int previousReason = res.removedInfo.uninstallReasons.valueAt(i);
19149                         ps.setUninstallReason(previousReason, previousUserId);
19150                     }
19151                 }
19152 
19153                 // Set install reason for users that are having the package newly installed.
19154                 final int[] allUsersList = mUserManager.getUserIds();
19155                 if (userId == UserHandle.USER_ALL) {
19156                     // TODO(b/152629990): It appears that the package doesn't actually get newly
19157                     //  installed in this case, so the installReason shouldn't get modified?
19158                     for (int currentUserId : allUsersList) {
19159                         if (!previousUserIds.contains(currentUserId)) {
19160                             ps.setInstallReason(installReason, currentUserId);
19161                         }
19162                     }
19163                 } else if (!previousUserIds.contains(userId)) {
19164                     ps.setInstallReason(installReason, userId);
19165                 }
19166 
19167                 // TODO(b/169721400): generalize Incremental States and create a Callback object
19168                 // that can be used for all the packages.
19169                 final String codePath = ps.getPathString();
19170                 if (IncrementalManager.isIncrementalPath(codePath) && mIncrementalManager != null) {
19171                     final IncrementalStatesCallback incrementalStatesCallback =
19172                             new IncrementalStatesCallback(ps.name,
19173                                     UserHandle.getUid(userId, ps.appId),
19174                                     getInstalledUsers(ps, userId));
19175                     ps.setIncrementalStatesCallback(incrementalStatesCallback);
19176                     mIncrementalManager.registerLoadingProgressCallback(codePath,
19177                             new IncrementalProgressListener(ps.name));
19178                 }
19179 
19180                 // Ensure that the uninstall reason is UNKNOWN for users with the package installed.
19181                 for (int currentUserId : allUsersList) {
19182                     if (ps.getInstalled(currentUserId)) {
19183                         ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, currentUserId);
19184                     }
19185                 }
19186 
19187                 mSettings.writeKernelMappingLPr(ps);
19188 
19189                 final PermissionManagerServiceInternal.PackageInstalledParams.Builder
19190                         permissionParamsBuilder =
19191                         new PermissionManagerServiceInternal.PackageInstalledParams.Builder();
19192                 final boolean grantPermissions = (installArgs.installFlags
19193                         & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
19194                 if (grantPermissions) {
19195                     final List<String> grantedPermissions =
19196                             installArgs.installGrantPermissions != null
19197                                     ? Arrays.asList(installArgs.installGrantPermissions)
19198                                     : pkg.getRequestedPermissions();
19199                     permissionParamsBuilder.setGrantedPermissions(grantedPermissions);
19200                 }
19201                 final boolean allowlistAllRestrictedPermissions =
19202                         (installArgs.installFlags
19203                                 & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0;
19204                 final List<String> allowlistedRestrictedPermissions =
19205                         allowlistAllRestrictedPermissions ? pkg.getRequestedPermissions()
19206                         : installArgs.whitelistedRestrictedPermissions;
19207                 if (allowlistedRestrictedPermissions != null) {
19208                     permissionParamsBuilder.setAllowlistedRestrictedPermissions(
19209                             allowlistedRestrictedPermissions);
19210                 }
19211                 final int autoRevokePermissionsMode = installArgs.autoRevokePermissionsMode;
19212                 permissionParamsBuilder.setAutoRevokePermissionsMode(autoRevokePermissionsMode);
19213                 mPermissionManager.onPackageInstalled(pkg, permissionParamsBuilder.build(), userId);
19214             }
19215             res.name = pkgName;
19216             res.uid = pkg.getUid();
19217             res.pkg = pkg;
19218             res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
19219             //to update install status
19220             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
19221             writeSettingsLPrTEMP();
19222             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
19223         }
19224 
19225         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
19226     }
19227 
19228     private static class InstallRequest {
19229         public final InstallArgs args;
19230         public final PackageInstalledInfo installResult;
19231 
InstallRequest(InstallArgs args, PackageInstalledInfo res)19232         private InstallRequest(InstallArgs args, PackageInstalledInfo res) {
19233             this.args = args;
19234             this.installResult = res;
19235         }
19236     }
19237 
19238     @GuardedBy("mInstallLock")
installPackagesTracedLI(List<InstallRequest> requests)19239     private void installPackagesTracedLI(List<InstallRequest> requests) {
19240         try {
19241             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages");
19242             installPackagesLI(requests);
19243         } finally {
19244             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
19245         }
19246     }
19247 
19248     /**
19249      * Package state to commit to memory and disk after reconciliation has completed.
19250      */
19251     private static class CommitRequest {
19252         final Map<String, ReconciledPackage> reconciledPackages;
19253         @NonNull
19254         final int[] mAllUsers;
19255 
CommitRequest(Map<String, ReconciledPackage> reconciledPackages, @NonNull int[] allUsers)19256         private CommitRequest(Map<String, ReconciledPackage> reconciledPackages,
19257                 @NonNull int[] allUsers) {
19258             this.reconciledPackages = reconciledPackages;
19259             this.mAllUsers = allUsers;
19260         }
19261     }
19262 
19263     /**
19264      * Package scan results and related request details used to reconcile the potential addition of
19265      * one or more packages to the system.
19266      *
19267      * Reconcile will take a set of package details that need to be committed to the system and make
19268      * sure that they are valid in the context of the system and the other installing apps. Any
19269      * invalid state or app will result in a failed reconciliation and thus whatever operation (such
19270      * as install) led to the request.
19271      */
19272     private static class ReconcileRequest {
19273         public final Map<String, ScanResult> scannedPackages;
19274 
19275         public final Map<String, AndroidPackage> allPackages;
19276         public final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> sharedLibrarySource;
19277         public final Map<String, InstallArgs> installArgs;
19278         public final Map<String, PackageInstalledInfo> installResults;
19279         public final Map<String, PrepareResult> preparedPackages;
19280         public final Map<String, VersionInfo> versionInfos;
19281         public final Map<String, PackageSetting> lastStaticSharedLibSettings;
19282 
ReconcileRequest(Map<String, ScanResult> scannedPackages, Map<String, InstallArgs> installArgs, Map<String, PackageInstalledInfo> installResults, Map<String, PrepareResult> preparedPackages, Map<String, WatchedLongSparseArray<SharedLibraryInfo>> sharedLibrarySource, Map<String, AndroidPackage> allPackages, Map<String, VersionInfo> versionInfos, Map<String, PackageSetting> lastStaticSharedLibSettings)19283         private ReconcileRequest(Map<String, ScanResult> scannedPackages,
19284                 Map<String, InstallArgs> installArgs,
19285                 Map<String, PackageInstalledInfo> installResults,
19286                 Map<String, PrepareResult> preparedPackages,
19287                 Map<String, WatchedLongSparseArray<SharedLibraryInfo>> sharedLibrarySource,
19288                 Map<String, AndroidPackage> allPackages,
19289                 Map<String, VersionInfo> versionInfos,
19290                 Map<String, PackageSetting> lastStaticSharedLibSettings) {
19291             this.scannedPackages = scannedPackages;
19292             this.installArgs = installArgs;
19293             this.installResults = installResults;
19294             this.preparedPackages = preparedPackages;
19295             this.sharedLibrarySource = sharedLibrarySource;
19296             this.allPackages = allPackages;
19297             this.versionInfos = versionInfos;
19298             this.lastStaticSharedLibSettings = lastStaticSharedLibSettings;
19299         }
19300 
ReconcileRequest(Map<String, ScanResult> scannedPackages, Map<String, WatchedLongSparseArray<SharedLibraryInfo>> sharedLibrarySource, Map<String, AndroidPackage> allPackages, Map<String, VersionInfo> versionInfos, Map<String, PackageSetting> lastStaticSharedLibSettings)19301         private ReconcileRequest(Map<String, ScanResult> scannedPackages,
19302                 Map<String, WatchedLongSparseArray<SharedLibraryInfo>> sharedLibrarySource,
19303                 Map<String, AndroidPackage> allPackages,
19304                 Map<String, VersionInfo> versionInfos,
19305                 Map<String, PackageSetting> lastStaticSharedLibSettings) {
19306             this(scannedPackages, Collections.emptyMap(), Collections.emptyMap(),
19307                     Collections.emptyMap(), sharedLibrarySource, allPackages, versionInfos,
19308                     lastStaticSharedLibSettings);
19309         }
19310     }
19311     private static class ReconcileFailure extends PackageManagerException {
ReconcileFailure(String message)19312         ReconcileFailure(String message) {
19313             super("Reconcile failed: " + message);
19314         }
ReconcileFailure(int reason, String message)19315         ReconcileFailure(int reason, String message) {
19316             super(reason, "Reconcile failed: " + message);
19317         }
ReconcileFailure(PackageManagerException e)19318         ReconcileFailure(PackageManagerException e) {
19319             this(e.error, e.getMessage());
19320         }
19321     }
19322 
19323     /**
19324      * A container of all data needed to commit a package to in-memory data structures and to disk.
19325      * TODO: move most of the data contained here into a PackageSetting for commit.
19326      */
19327     private static class ReconciledPackage {
19328         public final ReconcileRequest request;
19329         public final PackageSetting pkgSetting;
19330         public final ScanResult scanResult;
19331         // TODO: Remove install-specific details from the reconcile result
19332         public final PackageInstalledInfo installResult;
19333         @Nullable public final PrepareResult prepareResult;
19334         @Nullable public final InstallArgs installArgs;
19335         public final DeletePackageAction deletePackageAction;
19336         public final List<SharedLibraryInfo> allowedSharedLibraryInfos;
19337         public final SigningDetails signingDetails;
19338         public final boolean sharedUserSignaturesChanged;
19339         public ArrayList<SharedLibraryInfo> collectedSharedLibraryInfos;
19340         public final boolean removeAppKeySetData;
19341 
ReconciledPackage(ReconcileRequest request, InstallArgs installArgs, PackageSetting pkgSetting, PackageInstalledInfo installResult, PrepareResult prepareResult, ScanResult scanResult, DeletePackageAction deletePackageAction, List<SharedLibraryInfo> allowedSharedLibraryInfos, SigningDetails signingDetails, boolean sharedUserSignaturesChanged, boolean removeAppKeySetData)19342         private ReconciledPackage(ReconcileRequest request,
19343                 InstallArgs installArgs,
19344                 PackageSetting pkgSetting,
19345                 PackageInstalledInfo installResult,
19346                 PrepareResult prepareResult,
19347                 ScanResult scanResult,
19348                 DeletePackageAction deletePackageAction,
19349                 List<SharedLibraryInfo> allowedSharedLibraryInfos,
19350                 SigningDetails signingDetails,
19351                 boolean sharedUserSignaturesChanged,
19352                 boolean removeAppKeySetData) {
19353             this.request = request;
19354             this.installArgs = installArgs;
19355             this.pkgSetting = pkgSetting;
19356             this.installResult = installResult;
19357             this.prepareResult = prepareResult;
19358             this.scanResult = scanResult;
19359             this.deletePackageAction = deletePackageAction;
19360             this.allowedSharedLibraryInfos = allowedSharedLibraryInfos;
19361             this.signingDetails = signingDetails;
19362             this.sharedUserSignaturesChanged = sharedUserSignaturesChanged;
19363             this.removeAppKeySetData = removeAppKeySetData;
19364         }
19365 
19366         /**
19367          * Returns a combined set of packages containing the packages already installed combined
19368          * with the package(s) currently being installed. The to-be installed packages take
19369          * precedence and may shadow already installed packages.
19370          */
getCombinedAvailablePackages()19371         private Map<String, AndroidPackage> getCombinedAvailablePackages() {
19372             final ArrayMap<String, AndroidPackage> combined =
19373                     new ArrayMap<>(request.allPackages.size() + request.scannedPackages.size());
19374 
19375             combined.putAll(request.allPackages);
19376 
19377             for (ScanResult scanResult : request.scannedPackages.values()) {
19378                 combined.put(scanResult.pkgSetting.name, scanResult.request.parsedPackage);
19379             }
19380 
19381             return combined;
19382         }
19383     }
19384 
19385     @GuardedBy("mLock")
reconcilePackagesLocked( final ReconcileRequest request, KeySetManagerService ksms, Injector injector)19386     private static Map<String, ReconciledPackage> reconcilePackagesLocked(
19387             final ReconcileRequest request, KeySetManagerService ksms, Injector injector)
19388             throws ReconcileFailure {
19389         final Map<String, ScanResult> scannedPackages = request.scannedPackages;
19390 
19391         final Map<String, ReconciledPackage> result = new ArrayMap<>(scannedPackages.size());
19392 
19393         // make a copy of the existing set of packages so we can combine them with incoming packages
19394         final ArrayMap<String, AndroidPackage> combinedPackages =
19395                 new ArrayMap<>(request.allPackages.size() + scannedPackages.size());
19396 
19397         combinedPackages.putAll(request.allPackages);
19398 
19399         final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> incomingSharedLibraries =
19400                 new ArrayMap<>();
19401 
19402         for (String installPackageName : scannedPackages.keySet()) {
19403             final ScanResult scanResult = scannedPackages.get(installPackageName);
19404 
19405             // add / replace existing with incoming packages
19406             combinedPackages.put(scanResult.pkgSetting.name, scanResult.request.parsedPackage);
19407 
19408             // in the first pass, we'll build up the set of incoming shared libraries
19409             final List<SharedLibraryInfo> allowedSharedLibInfos =
19410                     getAllowedSharedLibInfos(scanResult, request.sharedLibrarySource);
19411             final SharedLibraryInfo staticLib = scanResult.staticSharedLibraryInfo;
19412             if (allowedSharedLibInfos != null) {
19413                 for (SharedLibraryInfo info : allowedSharedLibInfos) {
19414                     if (!addSharedLibraryToPackageVersionMap(incomingSharedLibraries, info)) {
19415                         throw new ReconcileFailure("Static Shared Library " + staticLib.getName()
19416                                 + " is being installed twice in this set!");
19417                     }
19418                 }
19419             }
19420 
19421             // the following may be null if we're just reconciling on boot (and not during install)
19422             final InstallArgs installArgs = request.installArgs.get(installPackageName);
19423             final PackageInstalledInfo res = request.installResults.get(installPackageName);
19424             final PrepareResult prepareResult = request.preparedPackages.get(installPackageName);
19425             final boolean isInstall = installArgs != null;
19426             if (isInstall && (res == null || prepareResult == null)) {
19427                 throw new ReconcileFailure("Reconcile arguments are not balanced for "
19428                         + installPackageName + "!");
19429             }
19430 
19431             final DeletePackageAction deletePackageAction;
19432             // we only want to try to delete for non system apps
19433             if (isInstall && prepareResult.replace && !prepareResult.system) {
19434                 final boolean killApp = (scanResult.request.scanFlags & SCAN_DONT_KILL_APP) == 0;
19435                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA
19436                         | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
19437                 deletePackageAction = mayDeletePackageLocked(res.removedInfo,
19438                         prepareResult.originalPs, prepareResult.disabledPs,
19439                         deleteFlags, null /* all users */);
19440                 if (deletePackageAction == null) {
19441                     throw new ReconcileFailure(
19442                             PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE,
19443                             "May not delete " + installPackageName + " to replace");
19444                 }
19445             } else {
19446                 deletePackageAction = null;
19447             }
19448 
19449             final int scanFlags = scanResult.request.scanFlags;
19450             final int parseFlags = scanResult.request.parseFlags;
19451             final ParsedPackage parsedPackage = scanResult.request.parsedPackage;
19452 
19453             final PackageSetting disabledPkgSetting = scanResult.request.disabledPkgSetting;
19454             final PackageSetting lastStaticSharedLibSetting =
19455                     request.lastStaticSharedLibSettings.get(installPackageName);
19456             final PackageSetting signatureCheckPs =
19457                     (prepareResult != null && lastStaticSharedLibSetting != null)
19458                             ? lastStaticSharedLibSetting
19459                             : scanResult.pkgSetting;
19460             boolean removeAppKeySetData = false;
19461             boolean sharedUserSignaturesChanged = false;
19462             SigningDetails signingDetails = null;
19463             if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
19464                 if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
19465                     // We just determined the app is signed correctly, so bring
19466                     // over the latest parsed certs.
19467                 } else {
19468                     if ((parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) == 0) {
19469                         throw new ReconcileFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
19470                                 "Package " + parsedPackage.getPackageName()
19471                                         + " upgrade keys do not match the previously installed"
19472                                         + " version");
19473                     } else {
19474                         String msg = "System package " + parsedPackage.getPackageName()
19475                                 + " signature changed; retaining data.";
19476                         reportSettingsProblem(Log.WARN, msg);
19477                     }
19478                 }
19479                 signingDetails = parsedPackage.getSigningDetails();
19480             } else {
19481                 try {
19482                     final VersionInfo versionInfo = request.versionInfos.get(installPackageName);
19483                     final boolean compareCompat = isCompatSignatureUpdateNeeded(versionInfo);
19484                     final boolean compareRecover = isRecoverSignatureUpdateNeeded(versionInfo);
19485                     final boolean isRollback = installArgs != null
19486                             && installArgs.installReason == PackageManager.INSTALL_REASON_ROLLBACK;
19487                     final boolean compatMatch = verifySignatures(signatureCheckPs,
19488                             disabledPkgSetting, parsedPackage.getSigningDetails(), compareCompat,
19489                             compareRecover, isRollback);
19490                     // The new KeySets will be re-added later in the scanning process.
19491                     if (compatMatch) {
19492                         removeAppKeySetData = true;
19493                     }
19494                     // We just determined the app is signed correctly, so bring
19495                     // over the latest parsed certs.
19496                     signingDetails = parsedPackage.getSigningDetails();
19497 
19498 
19499                     // if this is is a sharedUser, check to see if the new package is signed by a
19500                     // newer
19501                     // signing certificate than the existing one, and if so, copy over the new
19502                     // details
19503                     if (signatureCheckPs.sharedUser != null) {
19504                         // Attempt to merge the existing lineage for the shared SigningDetails with
19505                         // the lineage of the new package; if the shared SigningDetails are not
19506                         // returned this indicates the new package added new signers to the lineage
19507                         // and/or changed the capabilities of existing signers in the lineage.
19508                         SigningDetails sharedSigningDetails =
19509                                 signatureCheckPs.sharedUser.signatures.mSigningDetails;
19510                         SigningDetails mergedDetails = sharedSigningDetails.mergeLineageWith(
19511                                 signingDetails);
19512                         if (mergedDetails != sharedSigningDetails) {
19513                             signatureCheckPs.sharedUser.signatures.mSigningDetails = mergedDetails;
19514                         }
19515                         if (signatureCheckPs.sharedUser.signaturesChanged == null) {
19516                             signatureCheckPs.sharedUser.signaturesChanged = Boolean.FALSE;
19517                         }
19518                     }
19519                 } catch (PackageManagerException e) {
19520                     if ((parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) == 0) {
19521                         throw new ReconcileFailure(e);
19522                     }
19523                     signingDetails = parsedPackage.getSigningDetails();
19524 
19525                     // If the system app is part of a shared user we allow that shared user to
19526                     // change
19527                     // signatures as well as part of an OTA. We still need to verify that the
19528                     // signatures
19529                     // are consistent within the shared user for a given boot, so only allow
19530                     // updating
19531                     // the signatures on the first package scanned for the shared user (i.e. if the
19532                     // signaturesChanged state hasn't been initialized yet in SharedUserSetting).
19533                     if (signatureCheckPs.sharedUser != null) {
19534                         final Signature[] sharedUserSignatures =
19535                                 signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures;
19536                         if (signatureCheckPs.sharedUser.signaturesChanged != null
19537                                 && compareSignatures(sharedUserSignatures,
19538                                 parsedPackage.getSigningDetails().signatures)
19539                                         != PackageManager.SIGNATURE_MATCH) {
19540                             if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 29) {
19541                                 // Mismatched signatures is an error and silently skipping system
19542                                 // packages will likely break the device in unforeseen ways.
19543                                 // However, we allow the device to boot anyway because, prior to Q,
19544                                 // vendors were not expecting the platform to crash in this
19545                                 // situation.
19546                                 // This WILL be a hard failure on any new API levels after Q.
19547                                 throw new ReconcileFailure(
19548                                         INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
19549                                         "Signature mismatch for shared user: "
19550                                                 + scanResult.pkgSetting.sharedUser);
19551                             } else {
19552                                 // Treat mismatched signatures on system packages using a shared
19553                                 // UID as
19554                                 // fatal for the system overall, rather than just failing to install
19555                                 // whichever package happened to be scanned later.
19556                                 throw new IllegalStateException(
19557                                         "Signature mismatch on system package "
19558                                                 + parsedPackage.getPackageName()
19559                                                 + " for shared user "
19560                                                 + scanResult.pkgSetting.sharedUser);
19561                             }
19562                         }
19563 
19564                         sharedUserSignaturesChanged = true;
19565                         signatureCheckPs.sharedUser.signatures.mSigningDetails =
19566                                 parsedPackage.getSigningDetails();
19567                         signatureCheckPs.sharedUser.signaturesChanged = Boolean.TRUE;
19568                     }
19569                     // File a report about this.
19570                     String msg = "System package " + parsedPackage.getPackageName()
19571                             + " signature changed; retaining data.";
19572                     reportSettingsProblem(Log.WARN, msg);
19573                 } catch (IllegalArgumentException e) {
19574                     // should never happen: certs matched when checking, but not when comparing
19575                     // old to new for sharedUser
19576                     throw new RuntimeException(
19577                             "Signing certificates comparison made on incomparable signing details"
19578                                     + " but somehow passed verifySignatures!", e);
19579                 }
19580             }
19581 
19582             result.put(installPackageName,
19583                     new ReconciledPackage(request, installArgs, scanResult.pkgSetting,
19584                             res, request.preparedPackages.get(installPackageName), scanResult,
19585                             deletePackageAction, allowedSharedLibInfos, signingDetails,
19586                             sharedUserSignaturesChanged, removeAppKeySetData));
19587         }
19588 
19589         for (String installPackageName : scannedPackages.keySet()) {
19590             // Check all shared libraries and map to their actual file path.
19591             // We only do this here for apps not on a system dir, because those
19592             // are the only ones that can fail an install due to this.  We
19593             // will take care of the system apps by updating all of their
19594             // library paths after the scan is done. Also during the initial
19595             // scan don't update any libs as we do this wholesale after all
19596             // apps are scanned to avoid dependency based scanning.
19597             final ScanResult scanResult = scannedPackages.get(installPackageName);
19598             if ((scanResult.request.scanFlags & SCAN_BOOTING) != 0
19599                     || (scanResult.request.parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR)
19600                     != 0) {
19601                 continue;
19602             }
19603             try {
19604                 result.get(installPackageName).collectedSharedLibraryInfos =
19605                         collectSharedLibraryInfos(scanResult.request.parsedPackage,
19606                                 combinedPackages, request.sharedLibrarySource,
19607                                 incomingSharedLibraries, injector.getCompatibility());
19608 
19609             } catch (PackageManagerException e) {
19610                 throw new ReconcileFailure(e.error, e.getMessage());
19611             }
19612         }
19613 
19614         return result;
19615     }
19616 
19617     /**
19618      * Compare the newly scanned package with current system state to see which of its declared
19619      * shared libraries should be allowed to be added to the system.
19620      */
getAllowedSharedLibInfos( ScanResult scanResult, Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingSharedLibraries)19621     private static List<SharedLibraryInfo> getAllowedSharedLibInfos(
19622             ScanResult scanResult,
19623             Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingSharedLibraries) {
19624         // Let's used the parsed package as scanResult.pkgSetting may be null
19625         final ParsedPackage parsedPackage = scanResult.request.parsedPackage;
19626         if (scanResult.staticSharedLibraryInfo == null
19627                 && scanResult.dynamicSharedLibraryInfos == null) {
19628             return null;
19629         }
19630 
19631         // Any app can add new static shared libraries
19632         if (scanResult.staticSharedLibraryInfo != null) {
19633             return Collections.singletonList(scanResult.staticSharedLibraryInfo);
19634         }
19635         final boolean hasDynamicLibraries = parsedPackage.isSystem()
19636                         && scanResult.dynamicSharedLibraryInfos != null;
19637         if (!hasDynamicLibraries) {
19638             return null;
19639         }
19640         final boolean isUpdatedSystemApp = scanResult.pkgSetting.getPkgState()
19641                 .isUpdatedSystemApp();
19642         // We may not yet have disabled the updated package yet, so be sure to grab the
19643         // current setting if that's the case.
19644         final PackageSetting updatedSystemPs = isUpdatedSystemApp
19645                 ? scanResult.request.disabledPkgSetting == null
19646                         ? scanResult.request.oldPkgSetting
19647                         : scanResult.request.disabledPkgSetting
19648                 : null;
19649         if (isUpdatedSystemApp && (updatedSystemPs.pkg == null
19650                 || updatedSystemPs.pkg.getLibraryNames() == null)) {
19651             Slog.w(TAG, "Package " + parsedPackage.getPackageName()
19652                     + " declares libraries that are not declared on the system image; skipping");
19653             return null;
19654         }
19655         final ArrayList<SharedLibraryInfo> infos =
19656                 new ArrayList<>(scanResult.dynamicSharedLibraryInfos.size());
19657         for (SharedLibraryInfo info : scanResult.dynamicSharedLibraryInfos) {
19658             final String name = info.getName();
19659             if (isUpdatedSystemApp) {
19660                 // New library entries can only be added through the
19661                 // system image.  This is important to get rid of a lot
19662                 // of nasty edge cases: for example if we allowed a non-
19663                 // system update of the app to add a library, then uninstalling
19664                 // the update would make the library go away, and assumptions
19665                 // we made such as through app install filtering would now
19666                 // have allowed apps on the device which aren't compatible
19667                 // with it.  Better to just have the restriction here, be
19668                 // conservative, and create many fewer cases that can negatively
19669                 // impact the user experience.
19670                 if (!updatedSystemPs.pkg.getLibraryNames().contains(name)) {
19671                     Slog.w(TAG, "Package " + parsedPackage.getPackageName()
19672                             + " declares library " + name
19673                             + " that is not declared on system image; skipping");
19674                     continue;
19675                 }
19676             }
19677             if (sharedLibExists(
19678                     name, SharedLibraryInfo.VERSION_UNDEFINED, existingSharedLibraries)) {
19679                 Slog.w(TAG, "Package " + parsedPackage.getPackageName() + " declares library "
19680                         + name + " that already exists; skipping");
19681                 continue;
19682             }
19683             infos.add(info);
19684         }
19685         return infos;
19686     }
19687 
19688     /**
19689      * Returns false if the adding shared library already exists in the map and so could not be
19690      * added.
19691      */
addSharedLibraryToPackageVersionMap( Map<String, WatchedLongSparseArray<SharedLibraryInfo>> target, SharedLibraryInfo library)19692     private static boolean addSharedLibraryToPackageVersionMap(
19693             Map<String, WatchedLongSparseArray<SharedLibraryInfo>> target,
19694             SharedLibraryInfo library) {
19695         final String name = library.getName();
19696         if (target.containsKey(name)) {
19697             if (library.getType() != SharedLibraryInfo.TYPE_STATIC) {
19698                 // We've already added this non-version-specific library to the map.
19699                 return false;
19700             } else if (target.get(name).indexOfKey(library.getLongVersion()) >= 0) {
19701                 // We've already added this version of a version-specific library to the map.
19702                 return false;
19703             }
19704         } else {
19705             target.put(name, new WatchedLongSparseArray<>());
19706         }
19707         target.get(name).put(library.getLongVersion(), library);
19708         return true;
19709     }
19710 
19711     @GuardedBy("mLock")
commitPackagesLocked(final CommitRequest request)19712     private void commitPackagesLocked(final CommitRequest request) {
19713         // TODO: remove any expected failures from this method; this should only be able to fail due
19714         //       to unavoidable errors (I/O, etc.)
19715         for (ReconciledPackage reconciledPkg : request.reconciledPackages.values()) {
19716             final ScanResult scanResult = reconciledPkg.scanResult;
19717             final ScanRequest scanRequest = scanResult.request;
19718             final ParsedPackage parsedPackage = scanRequest.parsedPackage;
19719             final String packageName = parsedPackage.getPackageName();
19720             final PackageInstalledInfo res = reconciledPkg.installResult;
19721 
19722             if (reconciledPkg.prepareResult.replace) {
19723                 AndroidPackage oldPackage = mPackages.get(packageName);
19724 
19725                 // Set the update and install times
19726                 PackageSetting deletedPkgSetting = getPackageSetting(oldPackage.getPackageName());
19727                 reconciledPkg.pkgSetting.firstInstallTime = deletedPkgSetting.firstInstallTime;
19728                 reconciledPkg.pkgSetting.lastUpdateTime = System.currentTimeMillis();
19729 
19730                 res.removedInfo.broadcastAllowList = mAppsFilter.getVisibilityAllowList(
19731                         reconciledPkg.pkgSetting, request.mAllUsers, mSettings.getPackagesLocked());
19732                 if (reconciledPkg.prepareResult.system) {
19733                     // Remove existing system package
19734                     removePackageLI(oldPackage, true);
19735                     if (!disableSystemPackageLPw(oldPackage)) {
19736                         // We didn't need to disable the .apk as a current system package,
19737                         // which means we are replacing another update that is already
19738                         // installed.  We need to make sure to delete the older one's .apk.
19739                         res.removedInfo.args = createInstallArgsForExisting(
19740                                 oldPackage.getPath(),
19741                                 getAppDexInstructionSets(
19742                                         AndroidPackageUtils.getPrimaryCpuAbi(oldPackage,
19743                                                 deletedPkgSetting),
19744                                         AndroidPackageUtils.getSecondaryCpuAbi(oldPackage,
19745                                                 deletedPkgSetting)));
19746                     } else {
19747                         res.removedInfo.args = null;
19748                     }
19749                 } else {
19750                     try {
19751                         // Settings will be written during the call to updateSettingsLI().
19752                         executeDeletePackageLIF(reconciledPkg.deletePackageAction, packageName,
19753                                 true, request.mAllUsers, false, parsedPackage);
19754                     } catch (SystemDeleteException e) {
19755                         if (mIsEngBuild) {
19756                             throw new RuntimeException("Unexpected failure", e);
19757                             // ignore; not possible for non-system app
19758                         }
19759                     }
19760                     // Successfully deleted the old package; proceed with replace.
19761 
19762                     // If deleted package lived in a container, give users a chance to
19763                     // relinquish resources before killing.
19764                     if (oldPackage.isExternalStorage()) {
19765                         if (DEBUG_INSTALL) {
19766                             Slog.i(TAG, "upgrading pkg " + oldPackage
19767                                     + " is ASEC-hosted -> UNAVAILABLE");
19768                         }
19769                         final int[] uidArray = new int[]{oldPackage.getUid()};
19770                         final ArrayList<String> pkgList = new ArrayList<>(1);
19771                         pkgList.add(oldPackage.getPackageName());
19772                         sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
19773                     }
19774 
19775                     // Update the in-memory copy of the previous code paths.
19776                     PackageSetting ps1 = mSettings.getPackageLPr(
19777                             reconciledPkg.prepareResult.existingPackage.getPackageName());
19778                     if ((reconciledPkg.installArgs.installFlags & PackageManager.DONT_KILL_APP)
19779                             == 0) {
19780                         if (ps1.mOldCodePaths == null) {
19781                             ps1.mOldCodePaths = new ArraySet<>();
19782                         }
19783                         Collections.addAll(ps1.mOldCodePaths, oldPackage.getBaseApkPath());
19784                         if (oldPackage.getSplitCodePaths() != null) {
19785                             Collections.addAll(ps1.mOldCodePaths, oldPackage.getSplitCodePaths());
19786                         }
19787                     } else {
19788                         ps1.mOldCodePaths = null;
19789                     }
19790 
19791                     if (reconciledPkg.installResult.returnCode
19792                             == PackageManager.INSTALL_SUCCEEDED) {
19793                         PackageSetting ps2 = mSettings.getPackageLPr(
19794                                 parsedPackage.getPackageName());
19795                         if (ps2 != null) {
19796                             res.removedInfo.removedForAllUsers = mPackages.get(ps2.name) == null;
19797                         }
19798                     }
19799                 }
19800             }
19801 
19802             AndroidPackage pkg = commitReconciledScanResultLocked(reconciledPkg, request.mAllUsers);
19803             updateSettingsLI(pkg, reconciledPkg.installArgs, request.mAllUsers, res);
19804 
19805             final PackageSetting ps = mSettings.getPackageLPr(packageName);
19806             if (ps != null) {
19807                 res.newUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
19808                 ps.setUpdateAvailable(false /*updateAvailable*/);
19809             }
19810             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
19811                 updateSequenceNumberLP(ps, res.newUsers);
19812                 updateInstantAppInstallerLocked(packageName);
19813             }
19814         }
19815         ApplicationPackageManager.invalidateGetPackagesForUidCache();
19816     }
19817 
19818     /**
19819      * Installs one or more packages atomically. This operation is broken up into four phases:
19820      * <ul>
19821      *     <li><b>Prepare</b>
19822      *         <br/>Analyzes any current install state, parses the package and does initial
19823      *         validation on it.</li>
19824      *     <li><b>Scan</b>
19825      *         <br/>Interrogates the parsed packages given the context collected in prepare.</li>
19826      *     <li><b>Reconcile</b>
19827      *         <br/>Validates scanned packages in the context of each other and the current system
19828      *         state to ensure that the install will be successful.
19829      *     <li><b>Commit</b>
19830      *         <br/>Commits all scanned packages and updates system state. This is the only place
19831      *         that system state may be modified in the install flow and all predictable errors
19832      *         must be determined before this phase.</li>
19833      * </ul>
19834      *
19835      * Failure at any phase will result in a full failure to install all packages.
19836      */
19837     @GuardedBy("mInstallLock")
installPackagesLI(List<InstallRequest> requests)19838     private void installPackagesLI(List<InstallRequest> requests) {
19839         final Map<String, ScanResult> preparedScans = new ArrayMap<>(requests.size());
19840         final Map<String, InstallArgs> installArgs = new ArrayMap<>(requests.size());
19841         final Map<String, PackageInstalledInfo> installResults = new ArrayMap<>(requests.size());
19842         final Map<String, PrepareResult> prepareResults = new ArrayMap<>(requests.size());
19843         final Map<String, VersionInfo> versionInfos = new ArrayMap<>(requests.size());
19844         final Map<String, PackageSetting> lastStaticSharedLibSettings =
19845                 new ArrayMap<>(requests.size());
19846         final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size());
19847         boolean success = false;
19848         try {
19849             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackagesLI");
19850             for (InstallRequest request : requests) {
19851                 // TODO(b/109941548): remove this once we've pulled everything from it and into
19852                 //                    scan, reconcile or commit.
19853                 final PrepareResult prepareResult;
19854                 try {
19855                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage");
19856                     prepareResult =
19857                             preparePackageLI(request.args, request.installResult);
19858                 } catch (PrepareFailure prepareFailure) {
19859                     request.installResult.setError(prepareFailure.error,
19860                             prepareFailure.getMessage());
19861                     request.installResult.origPackage = prepareFailure.conflictingPackage;
19862                     request.installResult.origPermission = prepareFailure.conflictingPermission;
19863                     return;
19864                 } finally {
19865                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
19866                 }
19867                 request.installResult.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
19868                 request.installResult.installerPackageName =
19869                         request.args.installSource.installerPackageName;
19870 
19871                 final String packageName = prepareResult.packageToScan.getPackageName();
19872                 prepareResults.put(packageName, prepareResult);
19873                 installResults.put(packageName, request.installResult);
19874                 installArgs.put(packageName, request.args);
19875                 try {
19876                     final ScanResult result = scanPackageTracedLI(
19877                             prepareResult.packageToScan, prepareResult.parseFlags,
19878                             prepareResult.scanFlags, System.currentTimeMillis(),
19879                             request.args.user, request.args.abiOverride);
19880                     if (null != preparedScans.put(result.pkgSetting.pkg.getPackageName(), result)) {
19881                         request.installResult.setError(
19882                                 PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE,
19883                                 "Duplicate package " + result.pkgSetting.pkg.getPackageName()
19884                                         + " in multi-package install request.");
19885                         return;
19886                     }
19887                     createdAppId.put(packageName, optimisticallyRegisterAppId(result));
19888                     versionInfos.put(result.pkgSetting.pkg.getPackageName(),
19889                             getSettingsVersionForPackage(result.pkgSetting.pkg));
19890                     if (result.staticSharedLibraryInfo != null) {
19891                         final PackageSetting sharedLibLatestVersionSetting =
19892                                 getSharedLibLatestVersionSetting(result);
19893                         if (sharedLibLatestVersionSetting != null) {
19894                             lastStaticSharedLibSettings.put(result.pkgSetting.pkg.getPackageName(),
19895                                     sharedLibLatestVersionSetting);
19896                         }
19897                     }
19898                 } catch (PackageManagerException e) {
19899                     request.installResult.setError("Scanning Failed.", e);
19900                     return;
19901                 }
19902             }
19903             ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs,
19904                     installResults,
19905                     prepareResults,
19906                     mSharedLibraries,
19907                     Collections.unmodifiableMap(mPackages), versionInfos,
19908                     lastStaticSharedLibSettings);
19909             CommitRequest commitRequest = null;
19910             synchronized (mLock) {
19911                 Map<String, ReconciledPackage> reconciledPackages;
19912                 try {
19913                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages");
19914                     reconciledPackages = reconcilePackagesLocked(
19915                             reconcileRequest, mSettings.getKeySetManagerService(), mInjector);
19916                 } catch (ReconcileFailure e) {
19917                     for (InstallRequest request : requests) {
19918                         request.installResult.setError("Reconciliation failed...", e);
19919                     }
19920                     return;
19921                 } finally {
19922                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
19923                 }
19924                 try {
19925                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "commitPackages");
19926                     commitRequest = new CommitRequest(reconciledPackages,
19927                             mUserManager.getUserIds());
19928                     commitPackagesLocked(commitRequest);
19929                     success = true;
19930                 } finally {
19931                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
19932                 }
19933             }
19934             executePostCommitSteps(commitRequest);
19935         } finally {
19936             if (success) {
19937                 for (InstallRequest request : requests) {
19938                     final InstallArgs args = request.args;
19939                     if (args.mDataLoaderType != DataLoaderType.INCREMENTAL) {
19940                         continue;
19941                     }
19942                     if (args.signingDetails.signatureSchemeVersion != SIGNING_BLOCK_V4) {
19943                         continue;
19944                     }
19945                     // For incremental installs, we bypass the verifier prior to install. Now
19946                     // that we know the package is valid, send a notice to the verifier with
19947                     // the root hash of the base.apk.
19948                     final String baseCodePath = request.installResult.pkg.getBaseApkPath();
19949                     final String[] splitCodePaths = request.installResult.pkg.getSplitCodePaths();
19950                     final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
19951                     final int verificationId = mPendingVerificationToken++;
19952                     final String rootHashString = PackageManagerServiceUtils
19953                             .buildVerificationRootHashString(baseCodePath, splitCodePaths);
19954                     broadcastPackageVerified(verificationId, originUri,
19955                             PackageManager.VERIFICATION_ALLOW, rootHashString,
19956                             args.mDataLoaderType, args.getUser());
19957                 }
19958             } else {
19959                 for (ScanResult result : preparedScans.values()) {
19960                     if (createdAppId.getOrDefault(result.request.parsedPackage.getPackageName(),
19961                             false)) {
19962                         cleanUpAppIdCreation(result);
19963                     }
19964                 }
19965                 // TODO(patb): create a more descriptive reason than unknown in future release
19966                 // mark all non-failure installs as UNKNOWN so we do not treat them as success
19967                 for (InstallRequest request : requests) {
19968                     if (request.installResult.freezer != null) {
19969                         request.installResult.freezer.close();
19970                     }
19971                     if (request.installResult.returnCode == PackageManager.INSTALL_SUCCEEDED) {
19972                         request.installResult.returnCode = PackageManager.INSTALL_UNKNOWN;
19973                     }
19974                 }
19975             }
19976             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
19977         }
19978     }
19979 
19980     /**
19981      * On successful install, executes remaining steps after commit completes and the package lock
19982      * is released. These are typically more expensive or require calls to installd, which often
19983      * locks on {@link #mLock}.
19984      */
executePostCommitSteps(CommitRequest commitRequest)19985     private void executePostCommitSteps(CommitRequest commitRequest) {
19986         final ArraySet<IncrementalStorage> incrementalStorages = new ArraySet<>();
19987         for (ReconciledPackage reconciledPkg : commitRequest.reconciledPackages.values()) {
19988             final boolean instantApp = ((reconciledPkg.scanResult.request.scanFlags
19989                             & PackageManagerService.SCAN_AS_INSTANT_APP) != 0);
19990             final AndroidPackage pkg = reconciledPkg.pkgSetting.pkg;
19991             final String packageName = pkg.getPackageName();
19992             final String codePath = pkg.getPath();
19993             final boolean onIncremental = mIncrementalManager != null
19994                     && isIncrementalPath(codePath);
19995             if (onIncremental) {
19996                 IncrementalStorage storage = mIncrementalManager.openStorage(codePath);
19997                 if (storage == null) {
19998                     throw new IllegalArgumentException(
19999                             "Install: null storage for incremental package " + packageName);
20000                 }
20001                 incrementalStorages.add(storage);
20002             }
20003             prepareAppDataAfterInstallLIF(pkg);
20004             if (reconciledPkg.prepareResult.clearCodeCache) {
20005                 clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
20006                         | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20007             }
20008             if (reconciledPkg.prepareResult.replace) {
20009                 mDexManager.notifyPackageUpdated(pkg.getPackageName(),
20010                         pkg.getBaseApkPath(), pkg.getSplitCodePaths());
20011             }
20012 
20013             // Prepare the application profiles for the new code paths.
20014             // This needs to be done before invoking dexopt so that any install-time profile
20015             // can be used for optimizations.
20016             mArtManagerService.prepareAppProfiles(
20017                     pkg,
20018                     resolveUserIds(reconciledPkg.installArgs.user.getIdentifier()),
20019                     /* updateReferenceProfileContent= */ true);
20020 
20021             // Compute the compilation reason from the installation scenario.
20022             final int compilationReason = mDexManager.getCompilationReasonForInstallScenario(
20023                     reconciledPkg.installArgs.mInstallScenario);
20024 
20025             // Construct the DexoptOptions early to see if we should skip running dexopt.
20026             //
20027             // Do not run PackageDexOptimizer through the local performDexOpt
20028             // method because `pkg` may not be in `mPackages` yet.
20029             //
20030             // Also, don't fail application installs if the dexopt step fails.
20031             final boolean isBackupOrRestore =
20032                     reconciledPkg.installArgs.installReason == INSTALL_REASON_DEVICE_RESTORE
20033                     || reconciledPkg.installArgs.installReason == INSTALL_REASON_DEVICE_SETUP;
20034 
20035             final int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE
20036                     | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE
20037                     | (isBackupOrRestore ? DexoptOptions.DEXOPT_FOR_RESTORE : 0);
20038             DexoptOptions dexoptOptions =
20039                     new DexoptOptions(packageName, compilationReason, dexoptFlags);
20040 
20041             // Check whether we need to dexopt the app.
20042             //
20043             // NOTE: it is IMPORTANT to call dexopt:
20044             //   - after doRename which will sync the package data from AndroidPackage and
20045             //     its corresponding ApplicationInfo.
20046             //   - after installNewPackageLIF or replacePackageLIF which will update result with the
20047             //     uid of the application (pkg.applicationInfo.uid).
20048             //     This update happens in place!
20049             //
20050             // We only need to dexopt if the package meets ALL of the following conditions:
20051             //   1) it is not an instant app or if it is then dexopt is enabled via gservices.
20052             //   2) it is not debuggable.
20053             //   3) it is not on Incremental File System.
20054             //
20055             // Note that we do not dexopt instant apps by default. dexopt can take some time to
20056             // complete, so we skip this step during installation. Instead, we'll take extra time
20057             // the first time the instant app starts. It's preferred to do it this way to provide
20058             // continuous progress to the useur instead of mysteriously blocking somewhere in the
20059             // middle of running an instant app. The default behaviour can be overridden
20060             // via gservices.
20061             //
20062             // Furthermore, dexopt may be skipped, depending on the install scenario and current
20063             // state of the device.
20064             //
20065             // TODO(b/174695087): instantApp and onIncremental should be removed and their install
20066             //       path moved to SCENARIO_FAST.
20067             final boolean performDexopt =
20068                     (!instantApp || Global.getInt(mContext.getContentResolver(),
20069                     Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
20070                     && !pkg.isDebuggable()
20071                     && (!onIncremental)
20072                     && dexoptOptions.isCompilationEnabled();
20073 
20074             if (performDexopt) {
20075                 // Compile the layout resources.
20076                 if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
20077                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "compileLayouts");
20078                     mViewCompiler.compileLayouts(pkg);
20079                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
20080                 }
20081 
20082                 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
20083                 ScanResult result = reconciledPkg.scanResult;
20084 
20085                 // This mirrors logic from commitReconciledScanResultLocked, where the library files
20086                 // needed for dexopt are assigned.
20087                 // TODO: Fix this to have 1 mutable PackageSetting for scan/install. If the previous
20088                 //  setting needs to be passed to have a comparison, hide it behind an immutable
20089                 //  interface. There's no good reason to have 3 different ways to access the real
20090                 //  PackageSetting object, only one of which is actually correct.
20091                 PackageSetting realPkgSetting = result.existingSettingCopied
20092                         ? result.request.pkgSetting : result.pkgSetting;
20093                 if (realPkgSetting == null) {
20094                     realPkgSetting = reconciledPkg.pkgSetting;
20095                 }
20096 
20097                 // Unfortunately, the updated system app flag is only tracked on this PackageSetting
20098                 boolean isUpdatedSystemApp = reconciledPkg.pkgSetting.getPkgState()
20099                         .isUpdatedSystemApp();
20100 
20101                 realPkgSetting.getPkgState().setUpdatedSystemApp(isUpdatedSystemApp);
20102 
20103                 mPackageDexOptimizer.performDexOpt(pkg, realPkgSetting,
20104                         null /* instructionSets */,
20105                         getOrCreateCompilerPackageStats(pkg),
20106                         mDexManager.getPackageUseInfoOrDefault(packageName),
20107                         dexoptOptions);
20108                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
20109             }
20110 
20111             // Notify BackgroundDexOptService that the package has been changed.
20112             // If this is an update of a package which used to fail to compile,
20113             // BackgroundDexOptService will remove it from its denylist.
20114             // TODO: Layering violation
20115             BackgroundDexOptService.notifyPackageChanged(packageName);
20116 
20117             notifyPackageChangeObserversOnUpdate(reconciledPkg);
20118         }
20119         waitForNativeBinariesExtraction(incrementalStorages);
20120     }
20121 
waitForNativeBinariesExtraction( ArraySet<IncrementalStorage> incrementalStorages)20122     static void waitForNativeBinariesExtraction(
20123             ArraySet<IncrementalStorage> incrementalStorages) {
20124         if (incrementalStorages.isEmpty()) {
20125             return;
20126         }
20127         try {
20128             // Native library extraction may take very long time: each page could potentially
20129             // wait for either 10s or 100ms (adb vs non-adb data loader), and that easily adds
20130             // up to a full watchdog timeout of 1 min, killing the system after that. It doesn't
20131             // make much sense as blocking here doesn't lock up the framework, but only blocks
20132             // the installation session and the following ones.
20133             Watchdog.getInstance().pauseWatchingCurrentThread("native_lib_extract");
20134             for (int i = 0; i < incrementalStorages.size(); ++i) {
20135                 IncrementalStorage storage = incrementalStorages.valueAtUnchecked(i);
20136                 storage.waitForNativeBinariesExtraction();
20137             }
20138         } finally {
20139             Watchdog.getInstance().resumeWatchingCurrentThread("native_lib_extract");
20140         }
20141     }
20142 
getInstalledUsers(PackageSetting ps, int userId)20143     private int[] getInstalledUsers(PackageSetting ps, int userId) {
20144         final int[] allUserIds = resolveUserIds(userId);
20145         final ArrayList<Integer> installedUserIdsList = new ArrayList<>();
20146         for (int i = 0; i < allUserIds.length; i++) {
20147             if (ps.getInstalled(allUserIds[i])) {
20148                 installedUserIdsList.add(allUserIds[i]);
20149             }
20150         }
20151         final int numInstalledUserId = installedUserIdsList.size();
20152         final int[] installedUserIds = new int[numInstalledUserId];
20153         for (int i = 0; i < numInstalledUserId; i++) {
20154             installedUserIds[i] = installedUserIdsList.get(i);
20155         }
20156         return installedUserIds;
20157     }
20158 
20159     /**
20160      * Package states callback, used to listen for package state changes and send broadcasts
20161      */
20162     private final class IncrementalStatesCallback implements IncrementalStates.Callback {
20163         private final String mPackageName;
20164         private final int mUid;
20165         private final int[] mInstalledUserIds;
IncrementalStatesCallback(String packageName, int uid, int[] installedUserIds)20166         IncrementalStatesCallback(String packageName, int uid, int[] installedUserIds) {
20167             mPackageName = packageName;
20168             mUid = uid;
20169             mInstalledUserIds = installedUserIds;
20170         }
20171 
20172         @Override
onPackageFullyLoaded()20173         public void onPackageFullyLoaded() {
20174             final SparseArray<int[]> newBroadcastAllowList;
20175             final String codePath;
20176             synchronized (mLock) {
20177                 final PackageSetting ps = mSettings.getPackageLPr(mPackageName);
20178                 if (ps == null) {
20179                     return;
20180                 }
20181                 newBroadcastAllowList = mAppsFilter.getVisibilityAllowList(
20182                         ps, mInstalledUserIds, mSettings.getPackagesLocked());
20183                 codePath = ps.getPathString();
20184             }
20185             // Unregister progress listener
20186             mIncrementalManager.unregisterLoadingProgressCallbacks(codePath);
20187             // Make sure the information is preserved
20188             scheduleWriteSettingsLocked();
20189         }
20190     }
20191 
20192     /**
20193      * Loading progress callback, used to listen for progress changes and update package setting
20194      */
20195     private class IncrementalProgressListener extends IPackageLoadingProgressCallback.Stub {
20196         private final String mPackageName;
IncrementalProgressListener(String packageName)20197         IncrementalProgressListener(String packageName) {
20198             mPackageName = packageName;
20199         }
20200 
20201         @Override
onPackageLoadingProgressChanged(float progress)20202         public void onPackageLoadingProgressChanged(float progress) {
20203             final PackageSetting ps;
20204             synchronized (mLock) {
20205                 ps = mSettings.getPackageLPr(mPackageName);
20206                 if (ps == null) {
20207                     return;
20208                 }
20209                 ps.setLoadingProgress(progress);
20210             }
20211         }
20212     }
20213 
getPackageSettingForUser(String packageName, int callingUid, int userId)20214     @Nullable PackageSetting getPackageSettingForUser(String packageName, int callingUid,
20215             int userId) {
20216         final PackageSetting ps;
20217         synchronized (mLock) {
20218             ps = mSettings.getPackageLPr(packageName);
20219             if (ps == null) {
20220                 Slog.w(TAG, "Failed to get package setting. Package " + packageName
20221                         + " is not installed");
20222                 return null;
20223             }
20224             if (!ps.getInstalled(userId)) {
20225                 Slog.w(TAG, "Failed to get package setting. Package " + packageName
20226                         + " is not installed for user " + userId);
20227                 return null;
20228             }
20229             if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
20230                 Slog.w(TAG, "Failed to get package setting. Package " + packageName
20231                         + " is not visible to the calling app");
20232                 return null;
20233             }
20234         }
20235         return ps;
20236     }
20237 
notifyPackageChangeObserversOnUpdate(ReconciledPackage reconciledPkg)20238     private void notifyPackageChangeObserversOnUpdate(ReconciledPackage reconciledPkg) {
20239       final PackageSetting pkgSetting = reconciledPkg.pkgSetting;
20240       final PackageInstalledInfo pkgInstalledInfo = reconciledPkg.installResult;
20241       final PackageRemovedInfo pkgRemovedInfo = pkgInstalledInfo.removedInfo;
20242 
20243       PackageChangeEvent pkgChangeEvent = new PackageChangeEvent();
20244       pkgChangeEvent.packageName = pkgSetting.pkg.getPackageName();
20245       pkgChangeEvent.version = pkgSetting.versionCode;
20246       pkgChangeEvent.lastUpdateTimeMillis = pkgSetting.lastUpdateTime;
20247       pkgChangeEvent.newInstalled = (pkgRemovedInfo == null || !pkgRemovedInfo.isUpdate);
20248       pkgChangeEvent.dataRemoved = (pkgRemovedInfo != null && pkgRemovedInfo.dataRemoved);
20249       pkgChangeEvent.isDeleted = false;
20250 
20251       notifyPackageChangeObservers(pkgChangeEvent);
20252     }
20253 
notifyPackageChangeObserversOnDelete(String packageName, long version)20254     private void notifyPackageChangeObserversOnDelete(String packageName, long version) {
20255       PackageChangeEvent pkgChangeEvent = new PackageChangeEvent();
20256       pkgChangeEvent.packageName = packageName;
20257       pkgChangeEvent.version = version;
20258       pkgChangeEvent.lastUpdateTimeMillis = 0L;
20259       pkgChangeEvent.newInstalled = false;
20260       pkgChangeEvent.dataRemoved = false;
20261       pkgChangeEvent.isDeleted = true;
20262 
20263       notifyPackageChangeObservers(pkgChangeEvent);
20264     }
20265 
notifyPackageChangeObservers(PackageChangeEvent event)20266     private void notifyPackageChangeObservers(PackageChangeEvent event) {
20267       try {
20268         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "notifyPackageChangeObservers");
20269         synchronized (mPackageChangeObservers) {
20270           for(IPackageChangeObserver observer : mPackageChangeObservers) {
20271             try {
20272               observer.onPackageChanged(event);
20273             } catch(RemoteException e) {
20274               Log.wtf(TAG, e);
20275             }
20276           }
20277         }
20278       } finally {
20279         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
20280       }
20281     }
20282 
20283     /**
20284      * The set of data needed to successfully install the prepared package. This includes data that
20285      * will be used to scan and reconcile the package.
20286      */
20287     private static class PrepareResult {
20288         public final boolean replace;
20289         public final int scanFlags;
20290         public final int parseFlags;
20291         @Nullable /* The original Package if it is being replaced, otherwise {@code null} */
20292         public final AndroidPackage existingPackage;
20293         public final ParsedPackage packageToScan;
20294         public final boolean clearCodeCache;
20295         public final boolean system;
20296         public final PackageSetting originalPs;
20297         public final PackageSetting disabledPs;
20298 
PrepareResult(boolean replace, int scanFlags, int parseFlags, AndroidPackage existingPackage, ParsedPackage packageToScan, boolean clearCodeCache, boolean system, PackageSetting originalPs, PackageSetting disabledPs)20299         private PrepareResult(boolean replace, int scanFlags,
20300                 int parseFlags, AndroidPackage existingPackage,
20301                 ParsedPackage packageToScan, boolean clearCodeCache, boolean system,
20302                 PackageSetting originalPs, PackageSetting disabledPs) {
20303             this.replace = replace;
20304             this.scanFlags = scanFlags;
20305             this.parseFlags = parseFlags;
20306             this.existingPackage = existingPackage;
20307             this.packageToScan = packageToScan;
20308             this.clearCodeCache = clearCodeCache;
20309             this.system = system;
20310             this.originalPs = originalPs;
20311             this.disabledPs = disabledPs;
20312         }
20313     }
20314 
20315     private static class PrepareFailure extends PackageManagerException {
20316 
20317         public String conflictingPackage;
20318         public String conflictingPermission;
20319 
PrepareFailure(int error)20320         PrepareFailure(int error) {
20321             super(error, "Failed to prepare for install.");
20322         }
20323 
PrepareFailure(int error, String detailMessage)20324         PrepareFailure(int error, String detailMessage) {
20325             super(error, detailMessage);
20326         }
20327 
PrepareFailure(String message, Exception e)20328         PrepareFailure(String message, Exception e) {
20329             super(e instanceof PackageParserException
20330                     ? ((PackageParserException) e).error
20331                     : ((PackageManagerException) e).error,
20332                     ExceptionUtils.getCompleteMessage(message, e));
20333         }
20334 
conflictsWithExistingPermission(String conflictingPermission, String conflictingPackage)20335         PrepareFailure conflictsWithExistingPermission(String conflictingPermission,
20336                 String conflictingPackage) {
20337             this.conflictingPermission = conflictingPermission;
20338             this.conflictingPackage = conflictingPackage;
20339             return this;
20340         }
20341     }
20342 
doesSignatureMatchForPermissions(@onNull String sourcePackageName, @NonNull ParsedPackage parsedPackage, int scanFlags)20343     private boolean doesSignatureMatchForPermissions(@NonNull String sourcePackageName,
20344             @NonNull ParsedPackage parsedPackage, int scanFlags) {
20345         // If the defining package is signed with our cert, it's okay.  This
20346         // also includes the "updating the same package" case, of course.
20347         // "updating same package" could also involve key-rotation.
20348 
20349         final PackageSetting sourcePackageSetting;
20350         synchronized (mLock) {
20351             sourcePackageSetting = mSettings.getPackageLPr(sourcePackageName);
20352         }
20353 
20354         final SigningDetails sourceSigningDetails = (sourcePackageSetting == null
20355                 ? SigningDetails.UNKNOWN : sourcePackageSetting.getSigningDetails());
20356         final KeySetManagerService ksms = mSettings.getKeySetManagerService();
20357         if (sourcePackageName.equals(parsedPackage.getPackageName())
20358                 && (ksms.shouldCheckUpgradeKeySetLocked(
20359                 sourcePackageSetting, scanFlags))) {
20360             return ksms.checkUpgradeKeySetLocked(sourcePackageSetting, parsedPackage);
20361         } else {
20362 
20363             // in the event of signing certificate rotation, we need to see if the
20364             // package's certificate has rotated from the current one, or if it is an
20365             // older certificate with which the current is ok with sharing permissions
20366             if (sourceSigningDetails.checkCapability(
20367                     parsedPackage.getSigningDetails(),
20368                     PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
20369                 return true;
20370             } else if (parsedPackage.getSigningDetails().checkCapability(
20371                     sourceSigningDetails,
20372                     PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
20373                 // the scanned package checks out, has signing certificate rotation
20374                 // history, and is newer; bring it over
20375                 synchronized (mLock) {
20376                     sourcePackageSetting.signatures.mSigningDetails =
20377                             parsedPackage.getSigningDetails();
20378                 }
20379                 return true;
20380             } else {
20381                 return false;
20382             }
20383         }
20384     }
20385 
20386     /*
20387      * Cannot properly check CANNOT_INSTALL_WITH_BAD_PERMISSION_GROUPS using CompatChanges
20388      * as this only works for packages that are installed
20389      *
20390      * TODO: Move logic for permission group compatibility into PermissionManagerService
20391      */
20392     @SuppressWarnings("AndroidFrameworkCompatChange")
cannotInstallWithBadPermissionGroups(ParsedPackage parsedPackage)20393     private static boolean cannotInstallWithBadPermissionGroups(ParsedPackage parsedPackage) {
20394         return parsedPackage.getTargetSdkVersion() >= Build.VERSION_CODES.S;
20395     }
20396 
20397     @GuardedBy("mInstallLock")
preparePackageLI(InstallArgs args, PackageInstalledInfo res)20398     private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res)
20399             throws PrepareFailure {
20400         final int installFlags = args.installFlags;
20401         final File tmpPackageFile = new File(args.getCodePath());
20402         final boolean onExternal = args.volumeUuid != null;
20403         final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
20404         final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
20405         final boolean virtualPreload =
20406                 ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
20407         final boolean isRollback = args.installReason == PackageManager.INSTALL_REASON_ROLLBACK;
20408         @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
20409         if (args.move != null) {
20410             // moving a complete application; perform an initial scan on the new install location
20411             scanFlags |= SCAN_INITIAL;
20412         }
20413         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
20414             scanFlags |= SCAN_DONT_KILL_APP;
20415         }
20416         if (instantApp) {
20417             scanFlags |= SCAN_AS_INSTANT_APP;
20418         }
20419         if (fullApp) {
20420             scanFlags |= SCAN_AS_FULL_APP;
20421         }
20422         if (virtualPreload) {
20423             scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
20424         }
20425 
20426         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
20427 
20428         // Validity check
20429         if (instantApp && onExternal) {
20430             Slog.i(TAG, "Incompatible ephemeral install; external=" + onExternal);
20431             throw new PrepareFailure(PackageManager.INSTALL_FAILED_SESSION_INVALID);
20432         }
20433 
20434         // Retrieve PackageSettings and parse package
20435         @ParseFlags final int parseFlags = mDefParseFlags | ParsingPackageUtils.PARSE_CHATTY
20436                 | ParsingPackageUtils.PARSE_ENFORCE_CODE
20437                 | (onExternal ? ParsingPackageUtils.PARSE_EXTERNAL_STORAGE : 0);
20438 
20439         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
20440         final ParsedPackage parsedPackage;
20441         try (PackageParser2 pp = mInjector.getPreparingPackageParser()) {
20442             parsedPackage = pp.parsePackage(tmpPackageFile, parseFlags, false);
20443             AndroidPackageUtils.validatePackageDexMetadata(parsedPackage);
20444         } catch (PackageParserException e) {
20445             throw new PrepareFailure("Failed parse during installPackageLI", e);
20446         } finally {
20447             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
20448         }
20449 
20450         // Instant apps have several additional install-time checks.
20451         if (instantApp) {
20452             if (parsedPackage.getTargetSdkVersion() < Build.VERSION_CODES.O) {
20453                 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
20454                                 + " does not target at least O");
20455                 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID,
20456                         "Instant app package must target at least O");
20457             }
20458             if (parsedPackage.getSharedUserId() != null) {
20459                 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
20460                         + " may not declare sharedUserId.");
20461                 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID,
20462                         "Instant app package may not declare a sharedUserId");
20463             }
20464         }
20465 
20466         if (parsedPackage.isStaticSharedLibrary()) {
20467             // Static shared libraries have synthetic package names
20468             renameStaticSharedLibraryPackage(parsedPackage);
20469 
20470             // No static shared libs on external storage
20471             if (onExternal) {
20472                 Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
20473                 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
20474                         "Packages declaring static-shared libs cannot be updated");
20475             }
20476         }
20477 
20478         String pkgName = res.name = parsedPackage.getPackageName();
20479         if (parsedPackage.isTestOnly()) {
20480             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
20481                 throw new PrepareFailure(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
20482             }
20483         }
20484 
20485         try {
20486             // either use what we've been given or parse directly from the APK
20487             if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
20488                 parsedPackage.setSigningDetails(args.signingDetails);
20489             } else {
20490                 parsedPackage.setSigningDetails(ParsingPackageUtils.getSigningDetails(
20491                         parsedPackage, false /* skipVerify */));
20492             }
20493         } catch (PackageParserException e) {
20494             throw new PrepareFailure("Failed collect during installPackageLI", e);
20495         }
20496 
20497         if (instantApp && parsedPackage.getSigningDetails().signatureSchemeVersion
20498                 < SignatureSchemeVersion.SIGNING_BLOCK_V2) {
20499             Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
20500                     + " is not signed with at least APK Signature Scheme v2");
20501             throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID,
20502                     "Instant app package must be signed with APK Signature Scheme v2 or greater");
20503         }
20504 
20505         boolean systemApp = false;
20506         boolean replace = false;
20507         synchronized (mLock) {
20508             // Check if installing already existing package
20509             if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
20510                 String oldName = mSettings.getRenamedPackageLPr(pkgName);
20511                 if (parsedPackage.getOriginalPackages().contains(oldName)
20512                         && mPackages.containsKey(oldName)) {
20513                     // This package is derived from an original package,
20514                     // and this device has been updating from that original
20515                     // name.  We must continue using the original name, so
20516                     // rename the new package here.
20517                     parsedPackage.setPackageName(oldName);
20518                     pkgName = parsedPackage.getPackageName();
20519                     replace = true;
20520                     if (DEBUG_INSTALL) {
20521                         Slog.d(TAG, "Replacing existing renamed package: oldName="
20522                                 + oldName + " pkgName=" + pkgName);
20523                     }
20524                 } else if (mPackages.containsKey(pkgName)) {
20525                     // This package, under its official name, already exists
20526                     // on the device; we should replace it.
20527                     replace = true;
20528                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
20529                 }
20530 
20531                 if (replace) {
20532                     // Prevent apps opting out from runtime permissions
20533                     AndroidPackage oldPackage = mPackages.get(pkgName);
20534                     final int oldTargetSdk = oldPackage.getTargetSdkVersion();
20535                     final int newTargetSdk = parsedPackage.getTargetSdkVersion();
20536                     if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
20537                             && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
20538                         throw new PrepareFailure(
20539                                 PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
20540                                 "Package " + parsedPackage.getPackageName()
20541                                         + " new target SDK " + newTargetSdk
20542                                         + " doesn't support runtime permissions but the old"
20543                                         + " target SDK " + oldTargetSdk + " does.");
20544                     }
20545                     // Prevent persistent apps from being updated
20546                     if (oldPackage.isPersistent()
20547                             && ((installFlags & PackageManager.INSTALL_STAGED) == 0)) {
20548                         throw new PrepareFailure(PackageManager.INSTALL_FAILED_INVALID_APK,
20549                                 "Package " + oldPackage.getPackageName() + " is a persistent app. "
20550                                         + "Persistent apps are not updateable.");
20551                     }
20552                 }
20553             }
20554 
20555             PackageSetting ps = mSettings.getPackageLPr(pkgName);
20556             if (ps != null) {
20557                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
20558 
20559                 // Static shared libs have same package with different versions where
20560                 // we internally use a synthetic package name to allow multiple versions
20561                 // of the same package, therefore we need to compare signatures against
20562                 // the package setting for the latest library version.
20563                 PackageSetting signatureCheckPs = ps;
20564                 if (parsedPackage.isStaticSharedLibrary()) {
20565                     SharedLibraryInfo libraryInfo = getLatestSharedLibraVersionLPr(parsedPackage);
20566                     if (libraryInfo != null) {
20567                         signatureCheckPs = mSettings.getPackageLPr(libraryInfo.getPackageName());
20568                     }
20569                 }
20570 
20571                 // Quick validity check that we're signed correctly if updating;
20572                 // we'll check this again later when scanning, but we want to
20573                 // bail early here before tripping over redefined permissions.
20574                 final KeySetManagerService ksms = mSettings.getKeySetManagerService();
20575                 if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
20576                     if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
20577                         throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
20578                                 + parsedPackage.getPackageName() + " upgrade keys do not match the "
20579                                 + "previously installed version");
20580                     }
20581                 } else {
20582                     try {
20583                         final boolean compareCompat = isCompatSignatureUpdateNeeded(parsedPackage);
20584                         final boolean compareRecover = isRecoverSignatureUpdateNeeded(
20585                                 parsedPackage);
20586                         // We don't care about disabledPkgSetting on install for now.
20587                         final boolean compatMatch = verifySignatures(signatureCheckPs, null,
20588                                 parsedPackage.getSigningDetails(), compareCompat, compareRecover,
20589                                 isRollback);
20590                         // The new KeySets will be re-added later in the scanning process.
20591                         if (compatMatch) {
20592                             synchronized (mLock) {
20593                                 ksms.removeAppKeySetDataLPw(parsedPackage.getPackageName());
20594                             }
20595                         }
20596                     } catch (PackageManagerException e) {
20597                         throw new PrepareFailure(e.error, e.getMessage());
20598                     }
20599                 }
20600 
20601                 if (ps.pkg != null) {
20602                     systemApp = ps.pkg.isSystem();
20603                 }
20604                 res.origUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
20605             }
20606 
20607             final int numGroups = ArrayUtils.size(parsedPackage.getPermissionGroups());
20608             for (int groupNum = 0; groupNum < numGroups; groupNum++) {
20609                 final ParsedPermissionGroup group =
20610                         parsedPackage.getPermissionGroups().get(groupNum);
20611                 final PermissionGroupInfo sourceGroup = getPermissionGroupInfo(group.getName(), 0);
20612 
20613                 if (sourceGroup != null
20614                         && cannotInstallWithBadPermissionGroups(parsedPackage)) {
20615                     final String sourcePackageName = sourceGroup.packageName;
20616 
20617                     if ((replace || !parsedPackage.getPackageName().equals(sourcePackageName))
20618                             && !doesSignatureMatchForPermissions(sourcePackageName, parsedPackage,
20619                             scanFlags)) {
20620                         EventLog.writeEvent(0x534e4554, "146211400", -1,
20621                                 parsedPackage.getPackageName());
20622 
20623                         throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION_GROUP,
20624                                 "Package "
20625                                         + parsedPackage.getPackageName()
20626                                         + " attempting to redeclare permission group "
20627                                         + group.getName() + " already owned by "
20628                                         + sourcePackageName);
20629                     }
20630                 }
20631             }
20632 
20633            // TODO: Move logic for checking permission compatibility into PermissionManagerService
20634             final int N = ArrayUtils.size(parsedPackage.getPermissions());
20635             for (int i = N - 1; i >= 0; i--) {
20636                 final ParsedPermission perm = parsedPackage.getPermissions().get(i);
20637                 final Permission bp = mPermissionManager.getPermissionTEMP(perm.getName());
20638 
20639                 // Don't allow anyone but the system to define ephemeral permissions.
20640                 if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
20641                         && !systemApp) {
20642                     Slog.w(TAG, "Non-System package " + parsedPackage.getPackageName()
20643                             + " attempting to delcare ephemeral permission "
20644                             + perm.getName() + "; Removing ephemeral.");
20645                     perm.setProtectionLevel(perm.getProtectionLevel() & ~PermissionInfo.PROTECTION_FLAG_INSTANT);
20646                 }
20647 
20648                 // Check whether the newly-scanned package wants to define an already-defined perm
20649                 if (bp != null) {
20650                     final String sourcePackageName = bp.getPackageName();
20651 
20652                     if (!doesSignatureMatchForPermissions(sourcePackageName, parsedPackage,
20653                             scanFlags)) {
20654                         // If the owning package is the system itself, we log but allow
20655                         // install to proceed; we fail the install on all other permission
20656                         // redefinitions.
20657                         if (!sourcePackageName.equals("android")) {
20658                             throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
20659                                     + parsedPackage.getPackageName()
20660                                     + " attempting to redeclare permission "
20661                                     + perm.getName() + " already owned by "
20662                                     + sourcePackageName)
20663                                     .conflictsWithExistingPermission(perm.getName(),
20664                                             sourcePackageName);
20665                         } else {
20666                             Slog.w(TAG, "Package " + parsedPackage.getPackageName()
20667                                     + " attempting to redeclare system permission "
20668                                     + perm.getName() + "; ignoring new declaration");
20669                             parsedPackage.removePermission(i);
20670                         }
20671                     } else if (!PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())) {
20672                         // Prevent apps to change protection level to dangerous from any other
20673                         // type as this would allow a privilege escalation where an app adds a
20674                         // normal/signature permission in other app's group and later redefines
20675                         // it as dangerous leading to the group auto-grant.
20676                         if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_MASK_BASE)
20677                                 == PermissionInfo.PROTECTION_DANGEROUS) {
20678                             if (bp != null && !bp.isRuntime()) {
20679                                 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
20680                                         + " trying to change a non-runtime permission "
20681                                         + perm.getName()
20682                                         + " to runtime; keeping old protection level");
20683                                 perm.setProtectionLevel(bp.getProtectionLevel());
20684                             }
20685                         }
20686                     }
20687                 }
20688 
20689                 if (perm.getGroup() != null
20690                         && cannotInstallWithBadPermissionGroups(parsedPackage)) {
20691                     boolean isPermGroupDefinedByPackage = false;
20692                     for (int groupNum = 0; groupNum < numGroups; groupNum++) {
20693                         if (parsedPackage.getPermissionGroups().get(groupNum).getName()
20694                                 .equals(perm.getGroup())) {
20695                             isPermGroupDefinedByPackage = true;
20696                             break;
20697                         }
20698                     }
20699 
20700                     if (!isPermGroupDefinedByPackage) {
20701                         final PermissionGroupInfo sourceGroup =
20702                                 getPermissionGroupInfo(perm.getGroup(), 0);
20703 
20704                         if (sourceGroup == null) {
20705                             EventLog.writeEvent(0x534e4554, "146211400", -1,
20706                                     parsedPackage.getPackageName());
20707 
20708                             throw new PrepareFailure(INSTALL_FAILED_BAD_PERMISSION_GROUP,
20709                                     "Package "
20710                                             + parsedPackage.getPackageName()
20711                                             + " attempting to declare permission "
20712                                             + perm.getName() + " in non-existing group "
20713                                             + perm.getGroup());
20714                         } else {
20715                             String groupSourcePackageName = sourceGroup.packageName;
20716 
20717                             if (!PLATFORM_PACKAGE_NAME.equals(groupSourcePackageName)
20718                                     && !doesSignatureMatchForPermissions(groupSourcePackageName,
20719                                     parsedPackage, scanFlags)) {
20720                                 EventLog.writeEvent(0x534e4554, "146211400", -1,
20721                                         parsedPackage.getPackageName());
20722 
20723                                 throw new PrepareFailure(INSTALL_FAILED_BAD_PERMISSION_GROUP,
20724                                         "Package "
20725                                                 + parsedPackage.getPackageName()
20726                                                 + " attempting to declare permission "
20727                                                 + perm.getName() + " in group "
20728                                                 + perm.getGroup() + " owned by package "
20729                                                 + groupSourcePackageName
20730                                                 + " with incompatible certificate");
20731                             }
20732                         }
20733                     }
20734                 }
20735             }
20736         }
20737 
20738         if (systemApp) {
20739             if (onExternal) {
20740                 // Abort update; system app can't be replaced with app on sdcard
20741                 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
20742                         "Cannot install updates to system apps on sdcard");
20743             } else if (instantApp) {
20744                 // Abort update; system app can't be replaced with an instant app
20745                 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID,
20746                         "Cannot update a system app with an instant app");
20747             }
20748         }
20749 
20750         if (args.move != null) {
20751             // We did an in-place move, so dex is ready to roll
20752             scanFlags |= SCAN_NO_DEX;
20753             scanFlags |= SCAN_MOVE;
20754 
20755             synchronized (mLock) {
20756                 final PackageSetting ps = mSettings.getPackageLPr(pkgName);
20757                 if (ps == null) {
20758                     res.setError(INSTALL_FAILED_INTERNAL_ERROR,
20759                             "Missing settings for moved package " + pkgName);
20760                 }
20761 
20762                 // We moved the entire application as-is, so bring over the
20763                 // previously derived ABI information.
20764                 parsedPackage.setPrimaryCpuAbi(ps.primaryCpuAbiString)
20765                         .setSecondaryCpuAbi(ps.secondaryCpuAbiString);
20766             }
20767 
20768         } else {
20769             // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
20770             scanFlags |= SCAN_NO_DEX;
20771 
20772             try {
20773                 PackageSetting pkgSetting;
20774                 synchronized (mLock) {
20775                     pkgSetting = mSettings.getPackageLPr(pkgName);
20776                 }
20777                 boolean isUpdatedSystemAppFromExistingSetting = pkgSetting != null
20778                         && pkgSetting.getPkgState().isUpdatedSystemApp();
20779                 final String abiOverride = deriveAbiOverride(args.abiOverride);
20780                 AndroidPackage oldPackage = mPackages.get(pkgName);
20781                 boolean isUpdatedSystemAppInferred = oldPackage != null && oldPackage.isSystem();
20782                 final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
20783                         derivedAbi = mInjector.getAbiHelper().derivePackageAbi(parsedPackage,
20784                         isUpdatedSystemAppFromExistingSetting || isUpdatedSystemAppInferred,
20785                         abiOverride, mAppLib32InstallDir);
20786                 derivedAbi.first.applyTo(parsedPackage);
20787                 derivedAbi.second.applyTo(parsedPackage);
20788             } catch (PackageManagerException pme) {
20789                 Slog.e(TAG, "Error deriving application ABI", pme);
20790                 throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
20791                         "Error deriving application ABI: " + pme.getMessage());
20792             }
20793         }
20794 
20795         if (!args.doRename(res.returnCode, parsedPackage)) {
20796             throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
20797         }
20798 
20799         try {
20800             setUpFsVerityIfPossible(parsedPackage);
20801         } catch (InstallerException | IOException | DigestException | NoSuchAlgorithmException e) {
20802             throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
20803                     "Failed to set up verity: " + e);
20804         }
20805 
20806         final PackageFreezer freezer =
20807                 freezePackageForInstall(pkgName, installFlags, "installPackageLI");
20808         boolean shouldCloseFreezerBeforeReturn = true;
20809         try {
20810             final AndroidPackage existingPackage;
20811             String renamedPackage = null;
20812             boolean sysPkg = false;
20813             int targetScanFlags = scanFlags;
20814             int targetParseFlags = parseFlags;
20815             final PackageSetting ps;
20816             final PackageSetting disabledPs;
20817             if (replace) {
20818                 if (parsedPackage.isStaticSharedLibrary()) {
20819                     // Static libs have a synthetic package name containing the version
20820                     // and cannot be updated as an update would get a new package name,
20821                     // unless this is installed from adb which is useful for development.
20822                     AndroidPackage existingPkg = mPackages.get(parsedPackage.getPackageName());
20823                     if (existingPkg != null
20824                             && (installFlags & PackageManager.INSTALL_FROM_ADB) == 0) {
20825                         throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PACKAGE,
20826                                 "Packages declaring "
20827                                         + "static-shared libs cannot be updated");
20828                     }
20829                 }
20830 
20831                 final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
20832 
20833                 final AndroidPackage oldPackage;
20834                 final String pkgName11 = parsedPackage.getPackageName();
20835                 final int[] allUsers;
20836                 final int[] installedUsers;
20837                 final int[] uninstalledUsers;
20838 
20839                 synchronized (mLock) {
20840                     oldPackage = mPackages.get(pkgName11);
20841                     existingPackage = oldPackage;
20842                     if (DEBUG_INSTALL) {
20843                         Slog.d(TAG,
20844                                 "replacePackageLI: new=" + parsedPackage + ", old=" + oldPackage);
20845                     }
20846 
20847                     ps = mSettings.getPackageLPr(pkgName11);
20848                     disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
20849 
20850                     // verify signatures are valid
20851                     final KeySetManagerService ksms = mSettings.getKeySetManagerService();
20852                     if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
20853                         if (!ksms.checkUpgradeKeySetLocked(ps, parsedPackage)) {
20854                             throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
20855                                     "New package not signed by keys specified by upgrade-keysets: "
20856                                             + pkgName11);
20857                         }
20858                     } else {
20859                         SigningDetails parsedPkgSigningDetails = parsedPackage.getSigningDetails();
20860                         SigningDetails oldPkgSigningDetails = oldPackage.getSigningDetails();
20861                         // default to original signature matching
20862                         if (!parsedPkgSigningDetails.checkCapability(oldPkgSigningDetails,
20863                                 SigningDetails.CertCapabilities.INSTALLED_DATA)
20864                                 && !oldPkgSigningDetails.checkCapability(parsedPkgSigningDetails,
20865                                 SigningDetails.CertCapabilities.ROLLBACK)) {
20866                             // Allow the update to proceed if this is a rollback and the parsed
20867                             // package's current signing key is the current signer or in the lineage
20868                             // of the old package; this allows a rollback to a previously installed
20869                             // version after an app's signing key has been rotated without requiring
20870                             // the rollback capability on the previous signing key.
20871                             if (!isRollback || !oldPkgSigningDetails.hasAncestorOrSelf(
20872                                     parsedPkgSigningDetails)) {
20873                                 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
20874                                         "New package has a different signature: " + pkgName11);
20875                             }
20876                         }
20877                     }
20878 
20879                     // don't allow a system upgrade unless the upgrade hash matches
20880                     if (oldPackage.getRestrictUpdateHash() != null && oldPackage.isSystem()) {
20881                         final byte[] digestBytes;
20882                         try {
20883                             final MessageDigest digest = MessageDigest.getInstance("SHA-512");
20884                             updateDigest(digest, new File(parsedPackage.getBaseApkPath()));
20885                             if (!ArrayUtils.isEmpty(parsedPackage.getSplitCodePaths())) {
20886                                 for (String path : parsedPackage.getSplitCodePaths()) {
20887                                     updateDigest(digest, new File(path));
20888                                 }
20889                             }
20890                             digestBytes = digest.digest();
20891                         } catch (NoSuchAlgorithmException | IOException e) {
20892                             throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
20893                                     "Could not compute hash: " + pkgName11);
20894                         }
20895                         if (!Arrays.equals(oldPackage.getRestrictUpdateHash(), digestBytes)) {
20896                             throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
20897                                     "New package fails restrict-update check: " + pkgName11);
20898                         }
20899                         // retain upgrade restriction
20900                         parsedPackage.setRestrictUpdateHash(oldPackage.getRestrictUpdateHash());
20901                     }
20902 
20903                     // Check for shared user id changes
20904                     String invalidPackageName = null;
20905                     if (!Objects.equals(oldPackage.getSharedUserId(),
20906                             parsedPackage.getSharedUserId())) {
20907                         invalidPackageName = parsedPackage.getPackageName();
20908                     }
20909 
20910                     if (invalidPackageName != null) {
20911                         throw new PrepareFailure(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
20912                                 "Package " + invalidPackageName + " tried to change user "
20913                                         + oldPackage.getSharedUserId());
20914                     }
20915 
20916                     // In case of rollback, remember per-user/profile install state
20917                     allUsers = mUserManager.getUserIds();
20918                     installedUsers = ps.queryInstalledUsers(allUsers, true);
20919                     uninstalledUsers = ps.queryInstalledUsers(allUsers, false);
20920 
20921 
20922                     // don't allow an upgrade from full to ephemeral
20923                     if (isInstantApp) {
20924                         if (args.user == null || args.user.getIdentifier() == UserHandle.USER_ALL) {
20925                             for (int currentUser : allUsers) {
20926                                 if (!ps.getInstantApp(currentUser)) {
20927                                     // can't downgrade from full to instant
20928                                     Slog.w(TAG,
20929                                             "Can't replace full app with instant app: " + pkgName11
20930                                                     + " for user: " + currentUser);
20931                                     throw new PrepareFailure(
20932                                             PackageManager.INSTALL_FAILED_SESSION_INVALID);
20933                                 }
20934                             }
20935                         } else if (!ps.getInstantApp(args.user.getIdentifier())) {
20936                             // can't downgrade from full to instant
20937                             Slog.w(TAG, "Can't replace full app with instant app: " + pkgName11
20938                                     + " for user: " + args.user.getIdentifier());
20939                             throw new PrepareFailure(
20940                                     PackageManager.INSTALL_FAILED_SESSION_INVALID);
20941                         }
20942                     }
20943                 }
20944 
20945                 // Update what is removed
20946                 res.removedInfo = new PackageRemovedInfo(this);
20947                 res.removedInfo.uid = oldPackage.getUid();
20948                 res.removedInfo.removedPackage = oldPackage.getPackageName();
20949                 res.removedInfo.installerPackageName = ps.installSource.installerPackageName;
20950                 res.removedInfo.isStaticSharedLib = parsedPackage.getStaticSharedLibName() != null;
20951                 res.removedInfo.isUpdate = true;
20952                 res.removedInfo.origUsers = installedUsers;
20953                 res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
20954                 for (int i = 0; i < installedUsers.length; i++) {
20955                     final int userId = installedUsers[i];
20956                     res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
20957                 }
20958                 res.removedInfo.uninstallReasons = new SparseArray<>(uninstalledUsers.length);
20959                 for (int i = 0; i < uninstalledUsers.length; i++) {
20960                     final int userId = uninstalledUsers[i];
20961                     res.removedInfo.uninstallReasons.put(userId, ps.getUninstallReason(userId));
20962                 }
20963 
20964                 sysPkg = oldPackage.isSystem();
20965                 if (sysPkg) {
20966                     // Set the system/privileged/oem/vendor/product flags as needed
20967                     final boolean privileged = oldPackage.isPrivileged();
20968                     final boolean oem = oldPackage.isOem();
20969                     final boolean vendor = oldPackage.isVendor();
20970                     final boolean product = oldPackage.isProduct();
20971                     final boolean odm = oldPackage.isOdm();
20972                     final boolean systemExt = oldPackage.isSystemExt();
20973                     final @ParseFlags int systemParseFlags = parseFlags;
20974                     final @ScanFlags int systemScanFlags = scanFlags
20975                             | SCAN_AS_SYSTEM
20976                             | (privileged ? SCAN_AS_PRIVILEGED : 0)
20977                             | (oem ? SCAN_AS_OEM : 0)
20978                             | (vendor ? SCAN_AS_VENDOR : 0)
20979                             | (product ? SCAN_AS_PRODUCT : 0)
20980                             | (odm ? SCAN_AS_ODM : 0)
20981                             | (systemExt ? SCAN_AS_SYSTEM_EXT : 0);
20982 
20983                     if (DEBUG_INSTALL) {
20984                         Slog.d(TAG, "replaceSystemPackageLI: new=" + parsedPackage
20985                                 + ", old=" + oldPackage);
20986                     }
20987                     res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
20988                     targetParseFlags = systemParseFlags;
20989                     targetScanFlags = systemScanFlags;
20990                 } else { // non system replace
20991                     replace = true;
20992                     if (DEBUG_INSTALL) {
20993                         Slog.d(TAG,
20994                                 "replaceNonSystemPackageLI: new=" + parsedPackage + ", old="
20995                                         + oldPackage);
20996                     }
20997                 }
20998             } else { // new package install
20999                 ps = null;
21000                 disabledPs = null;
21001                 replace = false;
21002                 existingPackage = null;
21003                 // Remember this for later, in case we need to rollback this install
21004                 String pkgName1 = parsedPackage.getPackageName();
21005 
21006                 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + parsedPackage);
21007 
21008                 // TODO(patb): MOVE TO RECONCILE
21009                 synchronized (mLock) {
21010                     renamedPackage = mSettings.getRenamedPackageLPr(pkgName1);
21011                     if (renamedPackage != null) {
21012                         // A package with the same name is already installed, though
21013                         // it has been renamed to an older name.  The package we
21014                         // are trying to install should be installed as an update to
21015                         // the existing one, but that has not been requested, so bail.
21016                         throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS,
21017                                 "Attempt to re-install " + pkgName1
21018                                         + " without first uninstalling package running as "
21019                                         + renamedPackage);
21020                     }
21021                     if (mPackages.containsKey(pkgName1)) {
21022                         // Don't allow installation over an existing package with the same name.
21023                         throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS,
21024                                 "Attempt to re-install " + pkgName1
21025                                         + " without first uninstalling.");
21026                     }
21027                 }
21028             }
21029             // we're passing the freezer back to be closed in a later phase of install
21030             shouldCloseFreezerBeforeReturn = false;
21031 
21032             return new PrepareResult(replace, targetScanFlags, targetParseFlags,
21033                     existingPackage, parsedPackage, replace /* clearCodeCache */, sysPkg,
21034                     ps, disabledPs);
21035         } finally {
21036             res.freezer = freezer;
21037             if (shouldCloseFreezerBeforeReturn) {
21038                 freezer.close();
21039             }
21040         }
21041     }
21042 
21043     /**
21044      * Set up fs-verity for the given package if possible.  This requires a feature flag of system
21045      * property to be enabled only if the kernel supports fs-verity.
21046      *
21047      * <p>When the feature flag is set to legacy mode, only APK is supported (with some experimental
21048      * kernel patches). In normal mode, all file format can be supported.
21049      */
setUpFsVerityIfPossible(AndroidPackage pkg)21050     private void setUpFsVerityIfPossible(AndroidPackage pkg) throws InstallerException,
21051             PrepareFailure, IOException, DigestException, NoSuchAlgorithmException {
21052         final boolean standardMode = PackageManagerServiceUtils.isApkVerityEnabled();
21053         final boolean legacyMode = PackageManagerServiceUtils.isLegacyApkVerityEnabled();
21054         if (!standardMode && !legacyMode) {
21055             return;
21056         }
21057 
21058         if (isIncrementalPath(pkg.getPath()) && IncrementalManager.getVersion()
21059                 < IncrementalManager.MIN_VERSION_TO_SUPPORT_FSVERITY) {
21060             return;
21061         }
21062 
21063         // Collect files we care for fs-verity setup.
21064         ArrayMap<String, String> fsverityCandidates = new ArrayMap<>();
21065         if (legacyMode) {
21066             synchronized (mLock) {
21067                 final PackageSetting ps = mSettings.getPackageLPr(pkg.getPackageName());
21068                 if (ps != null && ps.isPrivileged()) {
21069                     fsverityCandidates.put(pkg.getBaseApkPath(), null);
21070                     if (pkg.getSplitCodePaths() != null) {
21071                         for (String splitPath : pkg.getSplitCodePaths()) {
21072                             fsverityCandidates.put(splitPath, null);
21073                         }
21074                     }
21075                 }
21076             }
21077         } else {
21078             // NB: These files will become only accessible if the signing key is loaded in kernel's
21079             // .fs-verity keyring.
21080             fsverityCandidates.put(pkg.getBaseApkPath(),
21081                     VerityUtils.getFsveritySignatureFilePath(pkg.getBaseApkPath()));
21082 
21083             final String dmPath = DexMetadataHelper.buildDexMetadataPathForApk(
21084                     pkg.getBaseApkPath());
21085             if (new File(dmPath).exists()) {
21086                 fsverityCandidates.put(dmPath, VerityUtils.getFsveritySignatureFilePath(dmPath));
21087             }
21088 
21089             if (pkg.getSplitCodePaths() != null) {
21090                 for (String path : pkg.getSplitCodePaths()) {
21091                     fsverityCandidates.put(path, VerityUtils.getFsveritySignatureFilePath(path));
21092 
21093                     final String splitDmPath = DexMetadataHelper.buildDexMetadataPathForApk(path);
21094                     if (new File(splitDmPath).exists()) {
21095                         fsverityCandidates.put(splitDmPath,
21096                                 VerityUtils.getFsveritySignatureFilePath(splitDmPath));
21097                     }
21098                 }
21099             }
21100         }
21101 
21102         for (Map.Entry<String, String> entry : fsverityCandidates.entrySet()) {
21103             final String filePath = entry.getKey();
21104             final String signaturePath = entry.getValue();
21105 
21106             if (!legacyMode) {
21107                 // fs-verity is optional for now.  Only set up if signature is provided.
21108                 if (new File(signaturePath).exists() && !VerityUtils.hasFsverity(filePath)) {
21109                     try {
21110                         VerityUtils.setUpFsverity(filePath, signaturePath);
21111                     } catch (IOException e) {
21112                         throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
21113                                 "Failed to enable fs-verity: " + e);
21114                     }
21115                 }
21116                 continue;
21117             }
21118 
21119             // In legacy mode, fs-verity can only be enabled by process with CAP_SYS_ADMIN.
21120             final VerityUtils.SetupResult result = VerityUtils.generateApkVeritySetupData(filePath);
21121             if (result.isOk()) {
21122                 if (Build.IS_DEBUGGABLE) Slog.i(TAG, "Enabling verity to " + filePath);
21123                 final FileDescriptor fd = result.getUnownedFileDescriptor();
21124                 try {
21125                     final byte[] rootHash = VerityUtils.generateApkVerityRootHash(filePath);
21126                     try {
21127                         // A file may already have fs-verity, e.g. when reused during a split
21128                         // install. If the measurement succeeds, no need to attempt to set up.
21129                         mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
21130                     } catch (InstallerException e) {
21131                         mInstaller.installApkVerity(filePath, fd, result.getContentSize());
21132                         mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
21133                     }
21134                 } finally {
21135                     IoUtils.closeQuietly(fd);
21136                 }
21137             } else if (result.isFailed()) {
21138                 throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
21139                         "Failed to generate verity");
21140             }
21141         }
21142     }
21143 
isExternal(PackageSetting ps)21144     private static boolean isExternal(PackageSetting ps) {
21145         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
21146     }
21147 
isSystemApp(PackageSetting ps)21148     private static boolean isSystemApp(PackageSetting ps) {
21149         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
21150     }
21151 
isUpdatedSystemApp(PackageSetting ps)21152     private static boolean isUpdatedSystemApp(PackageSetting ps) {
21153         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
21154     }
21155 
getSettingsVersionForPackage(AndroidPackage pkg)21156     private VersionInfo getSettingsVersionForPackage(AndroidPackage pkg) {
21157         if (pkg.isExternalStorage()) {
21158             if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
21159                 return mSettings.getExternalVersion();
21160             } else {
21161                 return mSettings.findOrCreateVersion(pkg.getVolumeUuid());
21162             }
21163         } else {
21164             return mSettings.getInternalVersion();
21165         }
21166     }
21167 
21168     @Override
deletePackageAsUser(String packageName, int versionCode, IPackageDeleteObserver observer, int userId, int flags)21169     public void deletePackageAsUser(String packageName, int versionCode,
21170             IPackageDeleteObserver observer, int userId, int flags) {
21171         deletePackageVersioned(new VersionedPackage(packageName, versionCode),
21172                 new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
21173     }
21174 
21175     @Override
deleteExistingPackageAsUser(VersionedPackage versionedPackage, final IPackageDeleteObserver2 observer, final int userId)21176     public void deleteExistingPackageAsUser(VersionedPackage versionedPackage,
21177             final IPackageDeleteObserver2 observer, final int userId) {
21178         mContext.enforceCallingOrSelfPermission(
21179                 android.Manifest.permission.DELETE_PACKAGES, null);
21180         Preconditions.checkNotNull(versionedPackage);
21181         Preconditions.checkNotNull(observer);
21182         final String packageName = versionedPackage.getPackageName();
21183         final long versionCode = versionedPackage.getLongVersionCode();
21184 
21185         int installedForUsersCount = 0;
21186         synchronized (mLock) {
21187             // Normalize package name to handle renamed packages and static libs
21188             final String internalPkgName = resolveInternalPackageNameLPr(packageName, versionCode);
21189             final PackageSetting ps = mSettings.getPackageLPr(internalPkgName);
21190             if (ps != null) {
21191                 int[] installedUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
21192                 installedForUsersCount = installedUsers.length;
21193             }
21194         }
21195 
21196         if (installedForUsersCount > 1) {
21197             deletePackageVersionedInternal(versionedPackage, observer, userId, 0, true);
21198         } else {
21199             try {
21200                 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_INTERNAL_ERROR,
21201                         null);
21202             } catch (RemoteException re) {
21203             }
21204         }
21205     }
21206 
21207     @Override
deletePackageVersioned(VersionedPackage versionedPackage, final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags)21208     public void deletePackageVersioned(VersionedPackage versionedPackage,
21209             final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
21210         deletePackageVersionedInternal(versionedPackage, observer, userId, deleteFlags, false);
21211     }
21212 
deletePackageVersionedInternal(VersionedPackage versionedPackage, final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags, final boolean allowSilentUninstall)21213     private void deletePackageVersionedInternal(VersionedPackage versionedPackage,
21214             final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags,
21215             final boolean allowSilentUninstall) {
21216         final int callingUid = Binder.getCallingUid();
21217         mContext.enforceCallingOrSelfPermission(
21218                 android.Manifest.permission.DELETE_PACKAGES, null);
21219         final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
21220         Preconditions.checkNotNull(versionedPackage);
21221         Preconditions.checkNotNull(observer);
21222         Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
21223                 PackageManager.VERSION_CODE_HIGHEST,
21224                 Long.MAX_VALUE, "versionCode must be >= -1");
21225 
21226         final String packageName = versionedPackage.getPackageName();
21227         final long versionCode = versionedPackage.getLongVersionCode();
21228         final String internalPackageName;
21229 
21230         try {
21231             if (mInjector.getLocalService(ActivityTaskManagerInternal.class)
21232                     .isBaseOfLockedTask(packageName)) {
21233                 observer.onPackageDeleted(
21234                         packageName, PackageManager.DELETE_FAILED_APP_PINNED, null);
21235                 EventLog.writeEvent(0x534e4554, "127605586", -1, "");
21236                 return;
21237             }
21238         } catch (RemoteException e) {
21239             e.rethrowFromSystemServer();
21240         }
21241 
21242         synchronized (mLock) {
21243             // Normalize package name to handle renamed packages and static libs
21244             internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
21245         }
21246 
21247         final int uid = Binder.getCallingUid();
21248         if (!isOrphaned(internalPackageName)
21249                 && !allowSilentUninstall
21250                 && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
21251             mHandler.post(() -> {
21252                 try {
21253                     final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
21254                     intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
21255                     intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
21256                     observer.onUserActionRequired(intent);
21257                 } catch (RemoteException re) {
21258                 }
21259             });
21260             return;
21261         }
21262         final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
21263         final int[] users = deleteAllUsers ? mUserManager.getUserIds() : new int[]{userId};
21264         if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
21265             mContext.enforceCallingOrSelfPermission(
21266                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
21267                     "deletePackage for user " + userId);
21268         }
21269 
21270         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
21271             mHandler.post(() -> {
21272                 try {
21273                     observer.onPackageDeleted(packageName,
21274                             PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
21275                 } catch (RemoteException re) {
21276                 }
21277             });
21278             return;
21279         }
21280 
21281         if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
21282             mHandler.post(() -> {
21283                 try {
21284                     observer.onPackageDeleted(packageName,
21285                             PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
21286                 } catch (RemoteException re) {
21287                 }
21288             });
21289             return;
21290         }
21291 
21292         if (DEBUG_REMOVE) {
21293             Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
21294                     + " deleteAllUsers: " + deleteAllUsers + " version="
21295                     + (versionCode == PackageManager.VERSION_CODE_HIGHEST
21296                     ? "VERSION_CODE_HIGHEST" : versionCode));
21297         }
21298         // Queue up an async operation since the package deletion may take a little while.
21299         mHandler.post(() -> {
21300             int returnCode;
21301             final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
21302             boolean doDeletePackage = true;
21303             if (ps != null) {
21304                 final boolean targetIsInstantApp =
21305                         ps.getInstantApp(UserHandle.getUserId(callingUid));
21306                 doDeletePackage = !targetIsInstantApp
21307                         || canViewInstantApps;
21308             }
21309             if (doDeletePackage) {
21310                 if (!deleteAllUsers) {
21311                     returnCode = deletePackageX(internalPackageName, versionCode,
21312                             userId, deleteFlags, false /*removedBySystem*/);
21313                 } else {
21314                     int[] blockUninstallUserIds = getBlockUninstallForUsers(
21315                             internalPackageName, users);
21316                     // If nobody is blocking uninstall, proceed with delete for all users
21317                     if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
21318                         returnCode = deletePackageX(internalPackageName, versionCode,
21319                                 userId, deleteFlags, false /*removedBySystem*/);
21320                     } else {
21321                         // Otherwise uninstall individually for users with blockUninstalls=false
21322                         final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
21323                         for (int userId1 : users) {
21324                             if (!ArrayUtils.contains(blockUninstallUserIds, userId1)) {
21325                                 returnCode = deletePackageX(internalPackageName, versionCode,
21326                                         userId1, userFlags, false /*removedBySystem*/);
21327                                 if (returnCode != PackageManager.DELETE_SUCCEEDED) {
21328                                     Slog.w(TAG, "Package delete failed for user " + userId1
21329                                             + ", returnCode " + returnCode);
21330                                 }
21331                             }
21332                         }
21333                         // The app has only been marked uninstalled for certain users.
21334                         // We still need to report that delete was blocked
21335                         returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
21336                     }
21337                 }
21338             } else {
21339                 returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
21340             }
21341             try {
21342                 observer.onPackageDeleted(packageName, returnCode, null);
21343             } catch (RemoteException e) {
21344                 Log.i(TAG, "Observer no longer exists.");
21345             } //end catch
21346             notifyPackageChangeObserversOnDelete(packageName, versionCode);
21347         });
21348     }
21349 
resolveExternalPackageNameLPr(AndroidPackage pkg)21350     private String resolveExternalPackageNameLPr(AndroidPackage pkg) {
21351         return mComputer.resolveExternalPackageNameLPr(pkg);
21352     }
21353 
21354     @GuardedBy("mLock")
resolveInternalPackageNameLPr(String packageName, long versionCode)21355     private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
21356         return mComputer.resolveInternalPackageNameLPr(packageName, versionCode);
21357     }
21358 
isCallerVerifier(int callingUid)21359     boolean isCallerVerifier(int callingUid) {
21360         final int callingUserId = UserHandle.getUserId(callingUid);
21361         return mRequiredVerifierPackage != null &&
21362                 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
21363     }
21364 
isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName)21365     private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
21366         if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
21367               || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
21368             return true;
21369         }
21370         final int callingUserId = UserHandle.getUserId(callingUid);
21371         // If the caller installed the pkgName, then allow it to silently uninstall.
21372         if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
21373             return true;
21374         }
21375 
21376         // Allow package verifier to silently uninstall.
21377         if (mRequiredVerifierPackage != null &&
21378                 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
21379             return true;
21380         }
21381 
21382         // Allow package uninstaller to silently uninstall.
21383         if (mRequiredUninstallerPackage != null &&
21384                 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
21385             return true;
21386         }
21387 
21388         // Allow storage manager to silently uninstall.
21389         if (mStorageManagerPackage != null &&
21390                 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
21391             return true;
21392         }
21393 
21394         // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
21395         // uninstall for device owner provisioning.
21396         if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
21397                 == PERMISSION_GRANTED) {
21398             return true;
21399         }
21400 
21401         return false;
21402     }
21403 
getBlockUninstallForUsers(String packageName, int[] userIds)21404     private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
21405         int[] result = EMPTY_INT_ARRAY;
21406         for (int userId : userIds) {
21407             if (getBlockUninstallForUser(packageName, userId)) {
21408                 result = ArrayUtils.appendInt(result, userId);
21409             }
21410         }
21411         return result;
21412     }
21413 
21414     @Override
isPackageDeviceAdminOnAnyUser(String packageName)21415     public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
21416         final int callingUid = Binder.getCallingUid();
21417         if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
21418                 != PERMISSION_GRANTED) {
21419             EventLog.writeEvent(0x534e4554, "128599183", -1, "");
21420             throw new SecurityException(android.Manifest.permission.MANAGE_USERS
21421                     + " permission is required to call this API");
21422         }
21423         if (getInstantAppPackageName(callingUid) != null
21424                 && !isCallerSameApp(packageName, callingUid)) {
21425             return false;
21426         }
21427         return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
21428     }
21429 
isPackageDeviceAdmin(String packageName, int userId)21430     private boolean isPackageDeviceAdmin(String packageName, int userId) {
21431         final IDevicePolicyManager dpm = getDevicePolicyManager();
21432         try {
21433             if (dpm != null) {
21434                 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
21435                         /* callingUserOnly =*/ false);
21436                 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
21437                         : deviceOwnerComponentName.getPackageName();
21438                 // Does the package contains the device owner?
21439                 // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
21440                 // this check is probably not needed, since DO should be registered as a device
21441                 // admin on some user too. (Original bug for this: b/17657954)
21442                 if (packageName.equals(deviceOwnerPackageName)) {
21443                     return true;
21444                 }
21445                 // Does it contain a device admin for any user?
21446                 int[] users;
21447                 if (userId == UserHandle.USER_ALL) {
21448                     users = mUserManager.getUserIds();
21449                 } else {
21450                     users = new int[]{userId};
21451                 }
21452                 for (int i = 0; i < users.length; ++i) {
21453                     if (dpm.packageHasActiveAdmins(packageName, users[i])) {
21454                         return true;
21455                     }
21456                 }
21457             }
21458         } catch (RemoteException e) {
21459         }
21460         return false;
21461     }
21462 
21463     /** Returns the device policy manager interface. */
getDevicePolicyManager()21464     private IDevicePolicyManager getDevicePolicyManager() {
21465         if (mDevicePolicyManager == null) {
21466             // No need to synchronize; worst-case scenario it will be fetched twice.
21467             mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface(
21468                             ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
21469         }
21470         return mDevicePolicyManager;
21471     }
21472 
shouldKeepUninstalledPackageLPr(String packageName)21473     private boolean shouldKeepUninstalledPackageLPr(String packageName) {
21474         return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
21475     }
21476 
21477     /**
21478      *  This method is an internal method that could be get invoked either
21479      *  to delete an installed package or to clean up a failed installation.
21480      *  After deleting an installed package, a broadcast is sent to notify any
21481      *  listeners that the package has been removed. For cleaning up a failed
21482      *  installation, the broadcast is not necessary since the package's
21483      *  installation wouldn't have sent the initial broadcast either
21484      *  The key steps in deleting a package are
21485      *  deleting the package information in internal structures like mPackages,
21486      *  deleting the packages base directories through installd
21487      *  updating mSettings to reflect current status
21488      *  persisting settings for later use
21489      *  sending a broadcast if necessary
21490      *
21491      *  @param removedBySystem A boolean to indicate the package was removed automatically without
21492      *                         the user-initiated action.
21493      */
deletePackageX(String packageName, long versionCode, int userId, int deleteFlags, boolean removedBySystem)21494     int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags,
21495             boolean removedBySystem) {
21496         final PackageRemovedInfo info = new PackageRemovedInfo(this);
21497         final boolean res;
21498 
21499         final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
21500                 ? UserHandle.USER_ALL : userId;
21501 
21502         if (isPackageDeviceAdmin(packageName, removeUser)) {
21503             Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
21504             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
21505         }
21506 
21507         final PackageSetting uninstalledPs;
21508         final PackageSetting disabledSystemPs;
21509         final AndroidPackage pkg;
21510 
21511         // for the uninstall-updates case and restricted profiles, remember the per-
21512         // user handle installed state
21513         int[] allUsers;
21514         final int freezeUser;
21515         final SparseArray<TempUserState> priorUserStates;
21516         /** enabled state of the uninstalled application */
21517         synchronized (mLock) {
21518             uninstalledPs = mSettings.getPackageLPr(packageName);
21519             if (uninstalledPs == null) {
21520                 Slog.w(TAG, "Not removing non-existent package " + packageName);
21521                 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
21522             }
21523 
21524             if (versionCode != PackageManager.VERSION_CODE_HIGHEST
21525                     && uninstalledPs.versionCode != versionCode) {
21526                 Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
21527                         + uninstalledPs.versionCode + " != " + versionCode);
21528                 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
21529             }
21530 
21531             disabledSystemPs = mSettings.getDisabledSystemPkgLPr(packageName);
21532             // Static shared libs can be declared by any package, so let us not
21533             // allow removing a package if it provides a lib others depend on.
21534             pkg = mPackages.get(packageName);
21535 
21536             allUsers = mUserManager.getUserIds();
21537 
21538             if (pkg != null && pkg.getStaticSharedLibName() != null) {
21539                 SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(
21540                         pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion());
21541                 if (libraryInfo != null) {
21542                     for (int currUserId : allUsers) {
21543                         if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
21544                             continue;
21545                         }
21546                         List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
21547                                 libraryInfo, MATCH_KNOWN_PACKAGES, Process.SYSTEM_UID, currUserId);
21548                         if (!ArrayUtils.isEmpty(libClientPackages)) {
21549                             Slog.w(TAG, "Not removing package " + pkg.getManifestPackageName()
21550                                     + " hosting lib " + libraryInfo.getName() + " version "
21551                                     + libraryInfo.getLongVersion() + " used by " + libClientPackages
21552                                     + " for user " + currUserId);
21553                             return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
21554                         }
21555                     }
21556                 }
21557             }
21558 
21559             info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
21560 
21561             if (isUpdatedSystemApp(uninstalledPs)
21562                     && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
21563                 // We're downgrading a system app, which will apply to all users, so
21564                 // freeze them all during the downgrade
21565                 freezeUser = UserHandle.USER_ALL;
21566                 priorUserStates = new SparseArray<>();
21567                 for (int i = 0; i < allUsers.length; i++) {
21568                     PackageUserState userState = uninstalledPs.readUserState(allUsers[i]);
21569                     priorUserStates.put(allUsers[i],
21570                             new TempUserState(userState.enabled, userState.lastDisableAppCaller,
21571                                     userState.installed));
21572                 }
21573             } else {
21574                 freezeUser = removeUser;
21575                 priorUserStates = null;
21576             }
21577         }
21578 
21579         synchronized (mInstallLock) {
21580             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
21581             try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
21582                     deleteFlags, "deletePackageX")) {
21583                 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
21584                         deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
21585             }
21586             synchronized (mLock) {
21587                 if (res) {
21588                     if (pkg != null) {
21589                         mInstantAppRegistry.onPackageUninstalledLPw(pkg, uninstalledPs,
21590                                 info.removedUsers);
21591                     }
21592                     updateSequenceNumberLP(uninstalledPs, info.removedUsers);
21593                     updateInstantAppInstallerLocked(packageName);
21594                 }
21595             }
21596             ApplicationPackageManager.invalidateGetPackagesForUidCache();
21597         }
21598 
21599         if (res) {
21600             final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
21601             info.sendPackageRemovedBroadcasts(killApp, removedBySystem);
21602             info.sendSystemPackageUpdatedBroadcasts();
21603         }
21604         // Force a gc here.
21605         Runtime.getRuntime().gc();
21606         // Delete the resources here after sending the broadcast to let
21607         // other processes clean up before deleting resources.
21608         synchronized (mInstallLock) {
21609             if (info.args != null) {
21610                 info.args.doPostDeleteLI(true);
21611             }
21612 
21613             boolean reEnableStub = false;
21614 
21615             if (priorUserStates != null) {
21616                 synchronized (mLock) {
21617                     for (int i = 0; i < allUsers.length; i++) {
21618                         TempUserState priorUserState = priorUserStates.get(allUsers[i]);
21619                         int enabledState = priorUserState.enabledState;
21620                         PackageSetting pkgSetting = getPackageSetting(packageName);
21621                         pkgSetting.setEnabled(enabledState, allUsers[i],
21622                                 priorUserState.lastDisableAppCaller);
21623 
21624                         AndroidPackage aPkg = pkgSetting.getPkg();
21625                         boolean pkgEnabled = aPkg != null && aPkg.isEnabled();
21626                         if (!reEnableStub && priorUserState.installed
21627                                 && ((enabledState == COMPONENT_ENABLED_STATE_DEFAULT && pkgEnabled)
21628                                         || enabledState == COMPONENT_ENABLED_STATE_ENABLED)) {
21629                             reEnableStub = true;
21630                         }
21631                     }
21632                     mSettings.writeAllUsersPackageRestrictionsLPr();
21633                 }
21634             }
21635 
21636             final AndroidPackage stubPkg =
21637                     (disabledSystemPs == null) ? null : disabledSystemPs.pkg;
21638             if (stubPkg != null && stubPkg.isStub()) {
21639                 final PackageSetting stubPs;
21640                 synchronized (mLock) {
21641                     stubPs = mSettings.getPackageLPr(stubPkg.getPackageName());
21642                 }
21643 
21644                 if (stubPs != null) {
21645                     if (reEnableStub) {
21646                         if (DEBUG_COMPRESSION) {
21647                             Slog.i(TAG, "Enabling system stub after removal; pkg: "
21648                                     + stubPkg.getPackageName());
21649                         }
21650                         enableCompressedPackage(stubPkg, stubPs);
21651                     } else if (DEBUG_COMPRESSION) {
21652                         Slog.i(TAG, "System stub disabled for all users, leaving uncompressed "
21653                                 + "after removal; pkg: " + stubPkg.getPackageName());
21654                     }
21655                 }
21656             }
21657         }
21658 
21659         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
21660     }
21661 
21662     static class PackageRemovedInfo {
21663         final PackageSender packageSender;
21664         String removedPackage;
21665         String installerPackageName;
21666         int uid = -1;
21667         int removedAppId = -1;
21668         int[] origUsers;
21669         int[] removedUsers = null;
21670         int[] broadcastUsers = null;
21671         int[] instantUserIds = null;
21672         SparseArray<Integer> installReasons;
21673         SparseArray<Integer> uninstallReasons;
21674         boolean isRemovedPackageSystemUpdate = false;
21675         boolean isUpdate;
21676         boolean dataRemoved;
21677         boolean removedForAllUsers;
21678         boolean isStaticSharedLib;
21679         // a two dimensional array mapping userId to the set of appIds that can receive notice
21680         // of package changes
21681         SparseArray<int[]> broadcastAllowList;
21682         // Clean up resources deleted packages.
21683         InstallArgs args = null;
21684 
PackageRemovedInfo(PackageSender packageSender)21685         PackageRemovedInfo(PackageSender packageSender) {
21686             this.packageSender = packageSender;
21687         }
21688 
sendPackageRemovedBroadcasts(boolean killApp, boolean removedBySystem)21689         void sendPackageRemovedBroadcasts(boolean killApp, boolean removedBySystem) {
21690             sendPackageRemovedBroadcastInternal(killApp, removedBySystem);
21691         }
21692 
sendSystemPackageUpdatedBroadcasts()21693         void sendSystemPackageUpdatedBroadcasts() {
21694             if (isRemovedPackageSystemUpdate) {
21695                 sendSystemPackageUpdatedBroadcastsInternal();
21696             }
21697         }
21698 
sendSystemPackageUpdatedBroadcastsInternal()21699         private void sendSystemPackageUpdatedBroadcastsInternal() {
21700             Bundle extras = new Bundle(2);
21701             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
21702             extras.putBoolean(Intent.EXTRA_REPLACING, true);
21703             packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, extras,
21704                     0, null /*targetPackage*/, null, null, null, broadcastAllowList, null);
21705             packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage,
21706                     extras, 0, null /*targetPackage*/, null, null, null, broadcastAllowList, null);
21707             packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, null, 0,
21708                     removedPackage, null, null, null, null /* broadcastAllowList */,
21709                     getTemporaryAppAllowlistBroadcastOptions(REASON_PACKAGE_REPLACED).toBundle());
21710             if (installerPackageName != null) {
21711                 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
21712                         removedPackage, extras, 0 /*flags*/,
21713                         installerPackageName, null, null, null, null /* broadcastAllowList */,
21714                         null);
21715                 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
21716                         removedPackage, extras, 0 /*flags*/,
21717                         installerPackageName, null, null, null, null /* broadcastAllowList */,
21718                         null);
21719             }
21720         }
21721 
sendPackageRemovedBroadcastInternal(boolean killApp, boolean removedBySystem)21722         private void sendPackageRemovedBroadcastInternal(boolean killApp, boolean removedBySystem) {
21723             // Don't send static shared library removal broadcasts as these
21724             // libs are visible only the the apps that depend on them an one
21725             // cannot remove the library if it has a dependency.
21726             if (isStaticSharedLib) {
21727                 return;
21728             }
21729             Bundle extras = new Bundle(2);
21730             final int removedUid = removedAppId >= 0  ? removedAppId : uid;
21731             extras.putInt(Intent.EXTRA_UID, removedUid);
21732             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
21733             extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
21734             extras.putBoolean(Intent.EXTRA_USER_INITIATED, !removedBySystem);
21735             if (isUpdate || isRemovedPackageSystemUpdate) {
21736                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
21737             }
21738             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
21739             if (removedPackage != null) {
21740                 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
21741                         removedPackage, extras, 0, null /*targetPackage*/, null,
21742                         broadcastUsers, instantUserIds, broadcastAllowList, null);
21743                 if (installerPackageName != null) {
21744                     packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
21745                             removedPackage, extras, 0 /*flags*/,
21746                             installerPackageName, null, broadcastUsers, instantUserIds, null, null);
21747                 }
21748                 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED_INTERNAL,
21749                         removedPackage, extras, 0 /*flags*/, PLATFORM_PACKAGE_NAME,
21750                         null /*finishedReceiver*/, broadcastUsers, instantUserIds,
21751                         broadcastAllowList, null /*bOptions*/);
21752                 if (dataRemoved && !isRemovedPackageSystemUpdate) {
21753                     packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
21754                             removedPackage, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null,
21755                             null, broadcastUsers, instantUserIds, broadcastAllowList, null);
21756                     packageSender.notifyPackageRemoved(removedPackage, removedUid);
21757                 }
21758             }
21759             if (removedAppId >= 0) {
21760                 // If a system app's updates are uninstalled the UID is not actually removed. Some
21761                 // services need to know the package name affected.
21762                 if (extras.getBoolean(Intent.EXTRA_REPLACING, false)) {
21763                     extras.putString(Intent.EXTRA_PACKAGE_NAME, removedPackage);
21764                 }
21765 
21766                 packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
21767                         null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
21768                         null, null, broadcastUsers, instantUserIds, broadcastAllowList, null);
21769             }
21770         }
21771 
populateUsers(int[] userIds, PackageSetting deletedPackageSetting)21772         void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
21773             removedUsers = userIds;
21774             if (removedUsers == null) {
21775                 broadcastUsers = null;
21776                 return;
21777             }
21778 
21779             broadcastUsers = EMPTY_INT_ARRAY;
21780             instantUserIds = EMPTY_INT_ARRAY;
21781             for (int i = userIds.length - 1; i >= 0; --i) {
21782                 final int userId = userIds[i];
21783                 if (deletedPackageSetting.getInstantApp(userId)) {
21784                     instantUserIds = ArrayUtils.appendInt(instantUserIds, userId);
21785                 } else {
21786                     broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
21787                 }
21788             }
21789         }
21790     }
21791 
21792     /*
21793      * This method deletes the package from internal data structures. If the DELETE_KEEP_DATA
21794      * flag is not set, the data directory is removed as well.
21795      * make sure this flag is set for partially installed apps. If not its meaningless to
21796      * delete a partially installed application.
21797      */
removePackageDataLIF(final PackageSetting deletedPs, @NonNull int[] allUserHandles, PackageRemovedInfo outInfo, int flags, boolean writeSettings)21798     private void removePackageDataLIF(final PackageSetting deletedPs, @NonNull int[] allUserHandles,
21799             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
21800         String packageName = deletedPs.name;
21801         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + deletedPs);
21802         // Retrieve object to delete permissions for shared user later on
21803         final AndroidPackage deletedPkg = deletedPs.pkg;
21804         if (outInfo != null) {
21805             outInfo.removedPackage = packageName;
21806             outInfo.installerPackageName = deletedPs.installSource.installerPackageName;
21807             outInfo.isStaticSharedLib = deletedPkg != null
21808                     && deletedPkg.getStaticSharedLibName() != null;
21809             outInfo.populateUsers(deletedPs == null ? null
21810                     : deletedPs.queryInstalledUsers(mUserManager.getUserIds(), true), deletedPs);
21811         }
21812 
21813         removePackageLI(deletedPs.name, (flags & PackageManager.DELETE_CHATTY) != 0);
21814 
21815         if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
21816             final AndroidPackage resolvedPkg;
21817             if (deletedPkg != null) {
21818                 resolvedPkg = deletedPkg;
21819             } else {
21820                 // We don't have a parsed package when it lives on an ejected
21821                 // adopted storage device, so fake something together
21822                 resolvedPkg = PackageImpl.buildFakeForDeletion(deletedPs.name,
21823                         deletedPs.volumeUuid);
21824             }
21825             destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
21826                     FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
21827             destroyAppProfilesLIF(resolvedPkg);
21828             if (outInfo != null) {
21829                 outInfo.dataRemoved = true;
21830             }
21831         }
21832 
21833         int removedAppId = -1;
21834 
21835         // writer
21836         boolean installedStateChanged = false;
21837         if (deletedPs != null) {
21838             if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
21839                 final SparseBooleanArray changedUsers = new SparseBooleanArray();
21840                 synchronized (mLock) {
21841                     mDomainVerificationManager.clearPackage(deletedPs.name);
21842                     mSettings.getKeySetManagerService().removeAppKeySetDataLPw(packageName);
21843                     mAppsFilter.removePackage(getPackageSetting(packageName));
21844                     removedAppId = mSettings.removePackageLPw(packageName);
21845                     if (outInfo != null) {
21846                         outInfo.removedAppId = removedAppId;
21847                     }
21848                     if (!mSettings.isDisabledSystemPackageLPr(packageName)) {
21849                         // If we don't have a disabled system package to reinstall, the package is
21850                         // really gone and its permission state should be removed.
21851                         final SharedUserSetting sus = deletedPs.getSharedUser();
21852                         List<AndroidPackage> sharedUserPkgs = sus != null ? sus.getPackages()
21853                                 : null;
21854                         if (sharedUserPkgs == null) {
21855                             sharedUserPkgs = Collections.emptyList();
21856                         }
21857                         mPermissionManager.onPackageUninstalled(packageName, deletedPs.appId,
21858                                 deletedPs.pkg, sharedUserPkgs, UserHandle.USER_ALL);
21859                     }
21860                     clearPackagePreferredActivitiesLPw(
21861                             deletedPs.name, changedUsers, UserHandle.USER_ALL);
21862                 }
21863                 if (changedUsers.size() > 0) {
21864                     updateDefaultHomeNotLocked(changedUsers);
21865                     postPreferredActivityChangedBroadcast(UserHandle.USER_ALL);
21866                 }
21867             }
21868             // make sure to preserve per-user disabled state if this removal was just
21869             // a downgrade of a system app to the factory package
21870             if (outInfo != null && outInfo.origUsers != null) {
21871                 if (DEBUG_REMOVE) {
21872                     Slog.d(TAG, "Propagating install state across downgrade");
21873                 }
21874                 for (int userId : allUserHandles) {
21875                     final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
21876                     if (DEBUG_REMOVE) {
21877                         Slog.d(TAG, "    user " + userId + " => " + installed);
21878                     }
21879                     if (installed != deletedPs.getInstalled(userId)) {
21880                         installedStateChanged = true;
21881                     }
21882                     deletedPs.setInstalled(installed, userId);
21883                     if (installed) {
21884                         deletedPs.setUninstallReason(UNINSTALL_REASON_UNKNOWN, userId);
21885                     }
21886                 }
21887             }
21888         }
21889         synchronized (mLock) {
21890             // can downgrade to reader
21891             if (writeSettings) {
21892                 // Save settings now
21893                 writeSettingsLPrTEMP();
21894             }
21895             if (installedStateChanged) {
21896                 mSettings.writeKernelMappingLPr(deletedPs);
21897             }
21898         }
21899         if (removedAppId != -1) {
21900             // A user ID was deleted here. Go through all users and remove it
21901             // from KeyStore.
21902             removeKeystoreDataIfNeeded(
21903                     mInjector.getUserManagerInternal(), UserHandle.USER_ALL, removedAppId);
21904         }
21905     }
21906 
resolveApexToScanPartition( ApexManager.ActiveApexInfo apexInfo)21907     private static @Nullable ScanPartition resolveApexToScanPartition(
21908             ApexManager.ActiveApexInfo apexInfo) {
21909         for (int i = 0, size = SYSTEM_PARTITIONS.size(); i < size; i++) {
21910             ScanPartition sp = SYSTEM_PARTITIONS.get(i);
21911             if (apexInfo.preInstalledApexPath.getAbsolutePath().startsWith(
21912                     sp.getFolder().getAbsolutePath())) {
21913                 return new ScanPartition(apexInfo.apexDirectory, sp, SCAN_AS_APK_IN_APEX);
21914             }
21915         }
21916         return null;
21917     }
21918 
21919     /*
21920      * Tries to delete system package.
21921      */
deleteSystemPackageLIF(DeletePackageAction action, PackageSetting deletedPs, @NonNull int[] allUserHandles, int flags, @Nullable PackageRemovedInfo outInfo, boolean writeSettings)21922     private void deleteSystemPackageLIF(DeletePackageAction action, PackageSetting deletedPs,
21923             @NonNull int[] allUserHandles, int flags, @Nullable PackageRemovedInfo outInfo,
21924             boolean writeSettings)
21925             throws SystemDeleteException {
21926         final boolean applyUserRestrictions = outInfo != null && (outInfo.origUsers != null);
21927         final AndroidPackage deletedPkg = deletedPs.pkg;
21928         // Confirm if the system package has been updated
21929         // An updated system app can be deleted. This will also have to restore
21930         // the system pkg from system partition
21931         // reader
21932         final PackageSetting disabledPs = action.disabledPs;
21933         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.getPackageName()
21934                 + " disabledPs=" + disabledPs);
21935         Slog.d(TAG, "Deleting system pkg from data partition");
21936 
21937         if (DEBUG_REMOVE) {
21938             if (applyUserRestrictions) {
21939                 Slog.d(TAG, "Remembering install states:");
21940                 for (int userId : allUserHandles) {
21941                     final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
21942                     Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
21943                 }
21944             }
21945         }
21946 
21947         if (outInfo != null) {
21948             // Delete the updated package
21949             outInfo.isRemovedPackageSystemUpdate = true;
21950         }
21951 
21952         if (disabledPs.versionCode < deletedPs.versionCode) {
21953             // Delete data for downgrades
21954             flags &= ~PackageManager.DELETE_KEEP_DATA;
21955         } else {
21956             // Preserve data by setting flag
21957             flags |= PackageManager.DELETE_KEEP_DATA;
21958         }
21959 
21960         deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
21961                 outInfo, writeSettings);
21962 
21963         // writer
21964         synchronized (mLock) {
21965             // NOTE: The system package always needs to be enabled; even if it's for
21966             // a compressed stub. If we don't, installing the system package fails
21967             // during scan [scanning checks the disabled packages]. We will reverse
21968             // this later, after we've "installed" the stub.
21969             // Reinstate the old system package
21970             enableSystemPackageLPw(disabledPs.pkg);
21971             // Remove any native libraries from the upgraded package.
21972             removeNativeBinariesLI(deletedPs);
21973         }
21974 
21975         // Install the system package
21976         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
21977         try {
21978             installPackageFromSystemLIF(disabledPs.getPathString(), allUserHandles,
21979                     outInfo == null ? null : outInfo.origUsers, writeSettings);
21980         } catch (PackageManagerException e) {
21981             Slog.w(TAG, "Failed to restore system package:" + deletedPkg.getPackageName() + ": "
21982                     + e.getMessage());
21983             // TODO(patb): can we avoid this; throw would come from scan...
21984             throw new SystemDeleteException(e);
21985         } finally {
21986             if (disabledPs.pkg.isStub()) {
21987                 // We've re-installed the stub; make sure it's disabled here. If package was
21988                 // originally enabled, we'll install the compressed version of the application
21989                 // and re-enable it afterward.
21990                 final PackageSetting stubPs = mSettings.getPackageLPr(deletedPkg.getPackageName());
21991                 if (stubPs != null) {
21992                     int userId = action.user == null
21993                             ? UserHandle.USER_ALL : action.user.getIdentifier();
21994                     if (userId == UserHandle.USER_ALL) {
21995                         for (int aUserId : allUserHandles) {
21996                             stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, aUserId, "android");
21997                         }
21998                     } else if (userId >= UserHandle.USER_SYSTEM) {
21999                         stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, userId, "android");
22000                     }
22001                 }
22002             }
22003         }
22004     }
22005 
22006     /**
22007      * Installs a package that's already on the system partition.
22008      */
installPackageFromSystemLIF(@onNull String codePathString, @NonNull int[] allUserHandles, @Nullable int[] origUserHandles, boolean writeSettings)22009     private AndroidPackage installPackageFromSystemLIF(@NonNull String codePathString,
22010             @NonNull int[] allUserHandles, @Nullable int[] origUserHandles, boolean writeSettings)
22011             throws PackageManagerException {
22012         final File codePath = new File(codePathString);
22013         @ParseFlags int parseFlags =
22014                 mDefParseFlags
22015                 | ParsingPackageUtils.PARSE_MUST_BE_APK
22016                 | ParsingPackageUtils.PARSE_IS_SYSTEM_DIR;
22017         @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
22018         for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
22019             ScanPartition partition = mDirsToScanAsSystem.get(i);
22020             if (partition.containsFile(codePath)) {
22021                 scanFlags |= partition.scanFlag;
22022                 if (partition.containsPrivApp(codePath)) {
22023                     scanFlags |= SCAN_AS_PRIVILEGED;
22024                 }
22025                 break;
22026             }
22027         }
22028 
22029         final AndroidPackage pkg =
22030                 scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
22031 
22032         PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.getPackageName());
22033 
22034         try {
22035             // update shared libraries for the newly re-installed system package
22036             updateSharedLibrariesLocked(pkg, pkgSetting, null, null,
22037                     Collections.unmodifiableMap(mPackages));
22038         } catch (PackageManagerException e) {
22039             Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
22040         }
22041 
22042         prepareAppDataAfterInstallLIF(pkg);
22043 
22044         // writer
22045         synchronized (mLock) {
22046             PackageSetting ps = mSettings.getPackageLPr(pkg.getPackageName());
22047 
22048             final boolean applyUserRestrictions = origUserHandles != null;
22049             if (applyUserRestrictions) {
22050                 boolean installedStateChanged = false;
22051                 if (DEBUG_REMOVE) {
22052                     Slog.d(TAG, "Propagating install state across reinstall");
22053                 }
22054                 for (int userId : allUserHandles) {
22055                     final boolean installed = ArrayUtils.contains(origUserHandles, userId);
22056                     if (DEBUG_REMOVE) {
22057                         Slog.d(TAG, "    user " + userId + " => " + installed);
22058                     }
22059                     if (installed != ps.getInstalled(userId)) {
22060                         installedStateChanged = true;
22061                     }
22062                     ps.setInstalled(installed, userId);
22063                     if (installed) {
22064                         ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, userId);
22065                     }
22066                 }
22067                 // Regardless of writeSettings we need to ensure that this restriction
22068                 // state propagation is persisted
22069                 mSettings.writeAllUsersPackageRestrictionsLPr();
22070                 if (installedStateChanged) {
22071                     mSettings.writeKernelMappingLPr(ps);
22072                 }
22073             }
22074 
22075             // The method below will take care of removing obsolete permissions and granting
22076             // install permissions.
22077             mPermissionManager.onPackageInstalled(pkg,
22078                     PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT,
22079                     UserHandle.USER_ALL);
22080             for (final int userId : allUserHandles) {
22081                 if (applyUserRestrictions) {
22082                     mSettings.writePermissionStateForUserLPr(userId, false);
22083                 }
22084             }
22085 
22086             // can downgrade to reader here
22087             if (writeSettings) {
22088                 writeSettingsLPrTEMP();
22089             }
22090         }
22091         return pkg;
22092     }
22093 
deleteInstalledPackageLIF(PackageSetting ps, boolean deleteCodeAndResources, int flags, @NonNull int[] allUserHandles, PackageRemovedInfo outInfo, boolean writeSettings)22094     private void deleteInstalledPackageLIF(PackageSetting ps,
22095             boolean deleteCodeAndResources, int flags, @NonNull int[] allUserHandles,
22096             PackageRemovedInfo outInfo, boolean writeSettings) {
22097         synchronized (mLock) {
22098             if (outInfo != null) {
22099                 outInfo.uid = ps.appId;
22100                 outInfo.broadcastAllowList = mAppsFilter.getVisibilityAllowList(ps,
22101                         allUserHandles, mSettings.getPackagesLocked());
22102             }
22103         }
22104 
22105         // Delete package data from internal structures and also remove data if flag is set
22106         removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
22107 
22108         // Delete application code and resources only for parent packages
22109         if (deleteCodeAndResources && (outInfo != null)) {
22110             outInfo.args = createInstallArgsForExisting(
22111                     ps.getPathString(), getAppDexInstructionSets(
22112                             ps.primaryCpuAbiString, ps.secondaryCpuAbiString));
22113             if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
22114         }
22115     }
22116 
22117     @Override
setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId)22118     public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
22119             int userId) {
22120         mContext.enforceCallingOrSelfPermission(
22121                 android.Manifest.permission.DELETE_PACKAGES, null);
22122         // TODO (b/157774108): This should fail on non-existent packages.
22123         synchronized (mLock) {
22124             // Cannot block uninstall of static shared libs as they are
22125             // considered a part of the using app (emulating static linking).
22126             // Also static libs are installed always on internal storage.
22127             AndroidPackage pkg = mPackages.get(packageName);
22128             if (pkg != null && pkg.getStaticSharedLibName() != null) {
22129                 Slog.w(TAG, "Cannot block uninstall of package: " + packageName
22130                         + " providing static shared library: " + pkg.getStaticSharedLibName());
22131                 return false;
22132             }
22133             mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
22134             mSettings.writePackageRestrictionsLPr(userId);
22135         }
22136         return true;
22137     }
22138 
22139     @Override
getBlockUninstallForUser(String packageName, int userId)22140     public boolean getBlockUninstallForUser(String packageName, int userId) {
22141         synchronized (mLock) {
22142             final PackageSetting ps = mSettings.getPackageLPr(packageName);
22143             if (ps == null || shouldFilterApplicationLocked(ps, Binder.getCallingUid(), userId)) {
22144                 return false;
22145             }
22146             return mSettings.getBlockUninstallLPr(userId, packageName);
22147         }
22148     }
22149 
22150     @Override
setRequiredForSystemUser(String packageName, boolean systemUserApp)22151     public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
22152         enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
22153         synchronized (mLock) {
22154             PackageSetting ps = mSettings.getPackageLPr(packageName);
22155             if (ps == null) {
22156                 Log.w(TAG, "Package doesn't exist: " + packageName);
22157                 return false;
22158             }
22159             if (systemUserApp) {
22160                 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
22161             } else {
22162                 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
22163             }
22164             writeSettingsLPrTEMP();
22165         }
22166         return true;
22167     }
22168 
22169     private static class DeletePackageAction {
22170         public final PackageSetting deletingPs;
22171         public final PackageSetting disabledPs;
22172         public final PackageRemovedInfo outInfo;
22173         public final int flags;
22174         public final UserHandle user;
22175 
DeletePackageAction(PackageSetting deletingPs, PackageSetting disabledPs, PackageRemovedInfo outInfo, int flags, UserHandle user)22176         private DeletePackageAction(PackageSetting deletingPs, PackageSetting disabledPs,
22177                 PackageRemovedInfo outInfo, int flags, UserHandle user) {
22178             this.deletingPs = deletingPs;
22179             this.disabledPs = disabledPs;
22180             this.outInfo = outInfo;
22181             this.flags = flags;
22182             this.user = user;
22183         }
22184     }
22185 
22186     /**
22187      * @return a {@link DeletePackageAction} if the provided package and related state may be
22188      * deleted, {@code null} otherwise.
22189      */
22190     @Nullable
22191     @GuardedBy("mLock")
mayDeletePackageLocked( PackageRemovedInfo outInfo, PackageSetting ps, @Nullable PackageSetting disabledPs, int flags, UserHandle user)22192     private static DeletePackageAction mayDeletePackageLocked(
22193             PackageRemovedInfo outInfo, PackageSetting ps, @Nullable PackageSetting disabledPs,
22194             int flags, UserHandle user) {
22195         if (ps == null) {
22196             return null;
22197         }
22198         if (isSystemApp(ps)) {
22199             final boolean deleteSystem = (flags & PackageManager.DELETE_SYSTEM_APP) != 0;
22200             final boolean deleteAllUsers =
22201                     user == null || user.getIdentifier() == UserHandle.USER_ALL;
22202             if ((!deleteSystem || deleteAllUsers) && disabledPs == null) {
22203                 Slog.w(TAG, "Attempt to delete unknown system package " + ps.pkg.getPackageName());
22204                 return null;
22205             }
22206             // Confirmed if the system package has been updated
22207             // An updated system app can be deleted. This will also have to restore
22208             // the system pkg from system partition reader
22209         }
22210         return new DeletePackageAction(ps, disabledPs, outInfo, flags, user);
22211     }
22212 
22213     /*
22214      * This method handles package deletion in general
22215      */
deletePackageLIF(@onNull String packageName, UserHandle user, boolean deleteCodeAndResources, @NonNull int[] allUserHandles, int flags, PackageRemovedInfo outInfo, boolean writeSettings, ParsedPackage replacingPackage)22216     private boolean deletePackageLIF(@NonNull String packageName, UserHandle user,
22217             boolean deleteCodeAndResources, @NonNull int[] allUserHandles, int flags,
22218             PackageRemovedInfo outInfo, boolean writeSettings,
22219             ParsedPackage replacingPackage) {
22220         final DeletePackageAction action;
22221         synchronized (mLock) {
22222             final PackageSetting ps = mSettings.getPackageLPr(packageName);
22223             final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
22224             action = mayDeletePackageLocked(outInfo, ps, disabledPs, flags, user);
22225         }
22226         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
22227         if (null == action) {
22228             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: action was null");
22229             return false;
22230         }
22231 
22232 
22233         try {
22234             executeDeletePackageLIF(action, packageName, deleteCodeAndResources,
22235                     allUserHandles, writeSettings, replacingPackage);
22236         } catch (SystemDeleteException e) {
22237             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: system deletion failure", e);
22238             return false;
22239         }
22240         return true;
22241     }
22242 
22243     private static class SystemDeleteException extends Exception {
22244         public final PackageManagerException reason;
22245 
SystemDeleteException(PackageManagerException reason)22246         private SystemDeleteException(PackageManagerException reason) {
22247             this.reason = reason;
22248         }
22249     }
22250 
22251     /** Deletes a package. Only throws when install of a disabled package fails. */
executeDeletePackageLIF(DeletePackageAction action, String packageName, boolean deleteCodeAndResources, @NonNull int[] allUserHandles, boolean writeSettings, ParsedPackage replacingPackage)22252     private void executeDeletePackageLIF(DeletePackageAction action,
22253             String packageName, boolean deleteCodeAndResources,
22254             @NonNull int[] allUserHandles, boolean writeSettings,
22255             ParsedPackage replacingPackage) throws SystemDeleteException {
22256         final PackageSetting ps = action.deletingPs;
22257         final PackageRemovedInfo outInfo = action.outInfo;
22258         final UserHandle user = action.user;
22259         final int flags = action.flags;
22260         final boolean systemApp = isSystemApp(ps);
22261 
22262         // We need to get the permission state before package state is (potentially) destroyed.
22263         final SparseBooleanArray hadSuspendAppsPermission = new SparseBooleanArray();
22264         for (int userId : allUserHandles) {
22265             hadSuspendAppsPermission.put(userId, checkPermission(Manifest.permission.SUSPEND_APPS,
22266                     packageName, userId) == PERMISSION_GRANTED);
22267         }
22268 
22269         final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
22270 
22271         if ((!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)
22272                 && userId != UserHandle.USER_ALL) {
22273             // The caller is asking that the package only be deleted for a single
22274             // user.  To do this, we just mark its uninstalled state and delete
22275             // its data. If this is a system app, we only allow this to happen if
22276             // they have set the special DELETE_SYSTEM_APP which requests different
22277             // semantics than normal for uninstalling system apps.
22278             final boolean clearPackageStateAndReturn;
22279             synchronized (mLock) {
22280                 markPackageUninstalledForUserLPw(ps, user);
22281                 if (!systemApp) {
22282                     // Do not uninstall the APK if an app should be cached
22283                     boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
22284                     if (ps.isAnyInstalled(mUserManager.getUserIds()) || keepUninstalledPackage) {
22285                         // Other users still have this package installed, so all
22286                         // we need to do is clear this user's data and save that
22287                         // it is uninstalled.
22288                         if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
22289                         clearPackageStateAndReturn = true;
22290                     } else {
22291                         // We need to set it back to 'installed' so the uninstall
22292                         // broadcasts will be sent correctly.
22293                         if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
22294                         ps.setInstalled(true, userId);
22295                         mSettings.writeKernelMappingLPr(ps);
22296                         clearPackageStateAndReturn = false;
22297                     }
22298                 } else {
22299                     // This is a system app, so we assume that the
22300                     // other users still have this package installed, so all
22301                     // we need to do is clear this user's data and save that
22302                     // it is uninstalled.
22303                     if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
22304                     clearPackageStateAndReturn = true;
22305                 }
22306             }
22307             if (clearPackageStateAndReturn) {
22308                 clearPackageStateForUserLIF(ps, userId, outInfo, flags);
22309                 synchronized (mLock) {
22310                     scheduleWritePackageRestrictionsLocked(user);
22311                 }
22312                 return;
22313             }
22314         }
22315 
22316         // TODO(b/109941548): break reasons for ret = false out into mayDelete method
22317         if (systemApp) {
22318             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
22319             // When an updated system application is deleted we delete the existing resources
22320             // as well and fall back to existing code in system partition
22321             deleteSystemPackageLIF(action, ps, allUserHandles, flags, outInfo, writeSettings);
22322         } else {
22323             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
22324             deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
22325                     outInfo, writeSettings);
22326         }
22327 
22328         // If the package removed had SUSPEND_APPS, unset any restrictions that might have been in
22329         // place for all affected users.
22330         int[] affectedUserIds = (outInfo != null) ? outInfo.removedUsers : null;
22331         if (affectedUserIds == null) {
22332             affectedUserIds = resolveUserIds(userId);
22333         }
22334         for (final int affectedUserId : affectedUserIds) {
22335             if (hadSuspendAppsPermission.get(affectedUserId)) {
22336                 unsuspendForSuspendingPackage(packageName, affectedUserId);
22337                 removeAllDistractingPackageRestrictions(affectedUserId);
22338             }
22339         }
22340 
22341         // Take a note whether we deleted the package for all users
22342         if (outInfo != null) {
22343             outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
22344         }
22345     }
22346 
22347     @GuardedBy("mLock")
markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user)22348     private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
22349         final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
22350                 ? mUserManager.getUserIds() : new int[] {user.getIdentifier()};
22351         for (int nextUserId : userIds) {
22352             if (DEBUG_REMOVE) {
22353                 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
22354             }
22355             ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
22356                     false /*installed*/,
22357                     true /*stopped*/,
22358                     true /*notLaunched*/,
22359                     false /*hidden*/,
22360                     0 /*distractionFlags*/,
22361                     false /*suspended*/,
22362                     null /*suspendParams*/,
22363                     false /*instantApp*/,
22364                     false /*virtualPreload*/,
22365                     null /*lastDisableAppCaller*/,
22366                     null /*enabledComponents*/,
22367                     null /*disabledComponents*/,
22368                     PackageManager.INSTALL_REASON_UNKNOWN,
22369                     PackageManager.UNINSTALL_REASON_UNKNOWN,
22370                     null /*harmfulAppWarning*/,
22371                     null /*splashScreenTheme*/);
22372         }
22373         mSettings.writeKernelMappingLPr(ps);
22374     }
22375 
clearPackageStateForUserLIF(PackageSetting ps, int userId, PackageRemovedInfo outInfo, int flags)22376     private void clearPackageStateForUserLIF(PackageSetting ps, int userId,
22377             PackageRemovedInfo outInfo, int flags) {
22378         final AndroidPackage pkg;
22379         synchronized (mLock) {
22380             pkg = mPackages.get(ps.name);
22381         }
22382 
22383         destroyAppProfilesLIF(pkg);
22384 
22385         final SharedUserSetting sus = ps.getSharedUser();
22386         List<AndroidPackage> sharedUserPkgs = sus != null ? sus.getPackages() : null;
22387         if (sharedUserPkgs == null) {
22388             sharedUserPkgs = Collections.emptyList();
22389         }
22390         final int[] userIds = (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds()
22391                 : new int[] {userId};
22392         for (int nextUserId : userIds) {
22393             if (DEBUG_REMOVE) {
22394                 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
22395                         + nextUserId);
22396             }
22397             if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
22398                 destroyAppDataLIF(pkg, nextUserId,
22399                         FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
22400             }
22401             removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), nextUserId, ps.appId);
22402             clearPackagePreferredActivities(ps.name, nextUserId);
22403             mDomainVerificationManager.clearPackageForUser(ps.name, nextUserId);
22404         }
22405         mPermissionManager.onPackageUninstalled(ps.name, ps.appId, pkg, sharedUserPkgs, userId);
22406 
22407         if (outInfo != null) {
22408             if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
22409                 outInfo.dataRemoved = true;
22410             }
22411             outInfo.removedPackage = ps.name;
22412             outInfo.installerPackageName = ps.installSource.installerPackageName;
22413             outInfo.isStaticSharedLib = pkg != null && pkg.getStaticSharedLibName() != null;
22414             outInfo.removedAppId = ps.appId;
22415             outInfo.removedUsers = userIds;
22416             outInfo.broadcastUsers = userIds;
22417         }
22418     }
22419 
22420     @Override
clearApplicationProfileData(String packageName)22421     public void clearApplicationProfileData(String packageName) {
22422         enforceSystemOrRoot("Only the system can clear all profile data");
22423 
22424         final AndroidPackage pkg;
22425         synchronized (mLock) {
22426             pkg = mPackages.get(packageName);
22427         }
22428 
22429         try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
22430             synchronized (mInstallLock) {
22431                 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
22432             }
22433         }
22434     }
22435 
22436     @Override
clearApplicationUserData(final String packageName, final IPackageDataObserver observer, final int userId)22437     public void clearApplicationUserData(final String packageName,
22438             final IPackageDataObserver observer, final int userId) {
22439         mContext.enforceCallingOrSelfPermission(
22440                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
22441 
22442         final int callingUid = Binder.getCallingUid();
22443         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
22444                 false /* checkShell */, "clear application data");
22445 
22446         final boolean filterApp;
22447         synchronized (mLock) {
22448             final PackageSetting ps = mSettings.getPackageLPr(packageName);
22449             filterApp = shouldFilterApplicationLocked(ps, callingUid, userId);
22450         }
22451         if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
22452             throw new SecurityException("Cannot clear data for a protected package: "
22453                     + packageName);
22454         }
22455         // Queue up an async operation since the package deletion may take a little while.
22456         mHandler.post(new Runnable() {
22457             public void run() {
22458                 mHandler.removeCallbacks(this);
22459                 final boolean succeeded;
22460                 if (!filterApp) {
22461                     try (PackageFreezer freezer = freezePackage(packageName,
22462                             "clearApplicationUserData")) {
22463                         synchronized (mInstallLock) {
22464                             succeeded = clearApplicationUserDataLIF(packageName, userId);
22465                         }
22466                         synchronized (mLock) {
22467                             mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
22468                                     packageName, userId);
22469                         }
22470                     }
22471                     if (succeeded) {
22472                         // invoke DeviceStorageMonitor's update method to clear any notifications
22473                         DeviceStorageMonitorInternal dsm = LocalServices
22474                                 .getService(DeviceStorageMonitorInternal.class);
22475                         if (dsm != null) {
22476                             dsm.checkMemory();
22477                         }
22478                         if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
22479                                 == PERMISSION_GRANTED) {
22480                             unsuspendForSuspendingPackage(packageName, userId);
22481                             removeAllDistractingPackageRestrictions(userId);
22482                             flushPackageRestrictionsAsUserInternalLocked(userId);
22483                         }
22484                     }
22485                 } else {
22486                     succeeded = false;
22487                 }
22488                 if (observer != null) {
22489                     try {
22490                         observer.onRemoveCompleted(packageName, succeeded);
22491                     } catch (RemoteException e) {
22492                         Log.i(TAG, "Observer no longer exists.");
22493                     }
22494                 } //end if observer
22495             } //end run
22496         });
22497     }
22498 
clearApplicationUserDataLIF(String packageName, int userId)22499     private boolean clearApplicationUserDataLIF(String packageName, int userId) {
22500         if (packageName == null) {
22501             Slog.w(TAG, "Attempt to delete null packageName.");
22502             return false;
22503         }
22504 
22505         // Try finding details about the requested package
22506         AndroidPackage pkg;
22507         PackageSetting ps;
22508         synchronized (mLock) {
22509             pkg = mPackages.get(packageName);
22510             ps = mSettings.getPackageLPr(packageName);
22511             if (pkg == null) {
22512                 if (ps != null) {
22513                     pkg = ps.pkg;
22514                 }
22515             }
22516         }
22517         if (pkg == null) {
22518             Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
22519             return false;
22520         }
22521         mPermissionManager.resetRuntimePermissions(pkg, userId);
22522 
22523         clearAppDataLIF(pkg, userId,
22524                 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
22525 
22526         final int appId = UserHandle.getAppId(pkg.getUid());
22527         removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), userId, appId);
22528 
22529         UserManagerInternal umInternal = mInjector.getUserManagerInternal();
22530         final int flags;
22531         if (umInternal.isUserUnlockingOrUnlocked(userId)) {
22532             flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22533         } else if (umInternal.isUserRunning(userId)) {
22534             flags = StorageManager.FLAG_STORAGE_DE;
22535         } else {
22536             flags = 0;
22537         }
22538         prepareAppDataContentsLIF(pkg, ps, userId, flags);
22539 
22540         return true;
22541     }
22542 
resetNetworkPolicies(int userId)22543     private void resetNetworkPolicies(int userId) {
22544         mInjector.getLocalService(NetworkPolicyManagerInternal.class).resetUserState(userId);
22545     }
22546 
22547     /**
22548      * Remove entries from the keystore daemon. Will only remove it if the
22549      * {@code appId} is valid.
22550      */
removeKeystoreDataIfNeeded(UserManagerInternal um, @UserIdInt int userId, @AppIdInt int appId)22551     private static void removeKeystoreDataIfNeeded(UserManagerInternal um, @UserIdInt int userId,
22552             @AppIdInt int appId) {
22553         if (appId < 0) {
22554             return;
22555         }
22556 
22557         final KeyStore keyStore = KeyStore.getInstance();
22558         if (keyStore != null) {
22559             if (userId == UserHandle.USER_ALL) {
22560                 for (final int individual : um.getUserIds()) {
22561                     keyStore.clearUid(UserHandle.getUid(individual, appId));
22562                 }
22563             } else {
22564                 keyStore.clearUid(UserHandle.getUid(userId, appId));
22565             }
22566         } else {
22567             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
22568         }
22569     }
22570 
22571     @Override
deleteApplicationCacheFiles(final String packageName, final IPackageDataObserver observer)22572     public void deleteApplicationCacheFiles(final String packageName,
22573             final IPackageDataObserver observer) {
22574         final int userId = UserHandle.getCallingUserId();
22575         deleteApplicationCacheFilesAsUser(packageName, userId, observer);
22576     }
22577 
22578     @Override
deleteApplicationCacheFilesAsUser(final String packageName, final int userId, final IPackageDataObserver observer)22579     public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
22580             final IPackageDataObserver observer) {
22581         final int callingUid = Binder.getCallingUid();
22582         if (mContext.checkCallingOrSelfPermission(
22583                 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES)
22584                 != PackageManager.PERMISSION_GRANTED) {
22585             // If the caller has the old delete cache permission, silently ignore.  Else throw.
22586             if (mContext.checkCallingOrSelfPermission(
22587                     android.Manifest.permission.DELETE_CACHE_FILES)
22588                     == PackageManager.PERMISSION_GRANTED) {
22589                 Slog.w(TAG, "Calling uid " + callingUid + " does not have " +
22590                         android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES +
22591                         ", silently ignoring");
22592                 return;
22593             }
22594             mContext.enforceCallingOrSelfPermission(
22595                     android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
22596         }
22597         enforceCrossUserPermission(callingUid, userId, /* requireFullPermission= */ true,
22598                 /* checkShell= */ false, "delete application cache files");
22599         final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
22600                 android.Manifest.permission.ACCESS_INSTANT_APPS);
22601 
22602         final AndroidPackage pkg;
22603         synchronized (mLock) {
22604             pkg = mPackages.get(packageName);
22605         }
22606 
22607         // Queue up an async operation since the package deletion may take a little while.
22608         mHandler.post(() -> {
22609             final PackageSetting ps = pkg == null ? null : getPackageSetting(pkg.getPackageName());
22610             boolean doClearData = true;
22611             if (ps != null) {
22612                 final boolean targetIsInstantApp =
22613                         ps.getInstantApp(UserHandle.getUserId(callingUid));
22614                 doClearData = !targetIsInstantApp
22615                         || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
22616             }
22617             if (doClearData) {
22618                 synchronized (mInstallLock) {
22619                     final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL;
22620                     // We're only clearing cache files, so we don't care if the
22621                     // app is unfrozen and still able to run
22622                     clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
22623                     clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
22624                 }
22625             }
22626             if (observer != null) {
22627                 try {
22628                     observer.onRemoveCompleted(packageName, true);
22629                 } catch (RemoteException e) {
22630                     Log.i(TAG, "Observer no longer exists.");
22631                 }
22632             }
22633         });
22634     }
22635 
22636     @Override
getPackageSizeInfo(final String packageName, int userId, final IPackageStatsObserver observer)22637     public void getPackageSizeInfo(final String packageName, int userId,
22638             final IPackageStatsObserver observer) {
22639         throw new UnsupportedOperationException(
22640                 "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
22641     }
22642 
22643     @GuardedBy("mInstallLock")
getPackageSizeInfoLI(String packageName, int userId, PackageStats stats)22644     private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
22645         final PackageSetting ps;
22646         synchronized (mLock) {
22647             ps = mSettings.getPackageLPr(packageName);
22648             if (ps == null) {
22649                 Slog.w(TAG, "Failed to find settings for " + packageName);
22650                 return false;
22651             }
22652         }
22653 
22654         final String[] packageNames = { packageName };
22655         final long[] ceDataInodes = { ps.getCeDataInode(userId) };
22656         final String[] codePaths = { ps.getPathString() };
22657 
22658         try {
22659             mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
22660                     ps.appId, ceDataInodes, codePaths, stats);
22661 
22662             // For now, ignore code size of packages on system partition
22663             if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
22664                 stats.codeSize = 0;
22665             }
22666 
22667             // External clients expect these to be tracked separately
22668             stats.dataSize -= stats.cacheSize;
22669 
22670         } catch (InstallerException e) {
22671             Slog.w(TAG, String.valueOf(e));
22672             return false;
22673         }
22674 
22675         return true;
22676     }
22677 
22678     @GuardedBy("mLock")
getUidTargetSdkVersionLockedLPr(int uid)22679     private int getUidTargetSdkVersionLockedLPr(int uid) {
22680         final int appId = UserHandle.getAppId(uid);
22681         final Object obj = mSettings.getSettingLPr(appId);
22682         if (obj instanceof SharedUserSetting) {
22683             final SharedUserSetting sus = (SharedUserSetting) obj;
22684             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
22685             final int numPackages = sus.packages.size();
22686             for (int index = 0; index < numPackages; index++) {
22687                 final PackageSetting ps = sus.packages.valueAt(index);
22688                 if (ps.pkg != null) {
22689                     int v = ps.pkg.getTargetSdkVersion();
22690                     if (v < vers) vers = v;
22691                 }
22692             }
22693             return vers;
22694         } else if (obj instanceof PackageSetting) {
22695             final PackageSetting ps = (PackageSetting) obj;
22696             if (ps.pkg != null) {
22697                 return ps.pkg.getTargetSdkVersion();
22698             }
22699         }
22700         return Build.VERSION_CODES.CUR_DEVELOPMENT;
22701     }
22702 
22703     @GuardedBy("mLock")
getPackageTargetSdkVersionLockedLPr(String packageName)22704     private int getPackageTargetSdkVersionLockedLPr(String packageName) {
22705         final AndroidPackage p = mPackages.get(packageName);
22706         if (p != null) {
22707             return p.getTargetSdkVersion();
22708         }
22709         return Build.VERSION_CODES.CUR_DEVELOPMENT;
22710     }
22711 
22712     @Override
addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId, boolean removeExisting)22713     public void addPreferredActivity(IntentFilter filter, int match,
22714             ComponentName[] set, ComponentName activity, int userId, boolean removeExisting) {
22715         addPreferredActivity(new WatchedIntentFilter(filter), match, set, activity, true, userId,
22716                 "Adding preferred", removeExisting);
22717     }
22718 
22719     /**
22720      * Variant that takes a {@link WatchedIntentFilter}
22721      */
addPreferredActivity(WatchedIntentFilter filter, int match, ComponentName[] set, ComponentName activity, boolean always, int userId, String opname, boolean removeExisting)22722     public void addPreferredActivity(WatchedIntentFilter filter, int match,
22723             ComponentName[] set, ComponentName activity, boolean always, int userId,
22724             String opname, boolean removeExisting) {
22725         // writer
22726         int callingUid = Binder.getCallingUid();
22727         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
22728                 false /* checkShell */, "add preferred activity");
22729         if (mContext.checkCallingOrSelfPermission(
22730                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
22731                 != PackageManager.PERMISSION_GRANTED) {
22732             synchronized (mLock) {
22733                 if (getUidTargetSdkVersionLockedLPr(callingUid)
22734                         < Build.VERSION_CODES.FROYO) {
22735                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
22736                             + callingUid);
22737                     return;
22738                 }
22739             }
22740             mContext.enforceCallingOrSelfPermission(
22741                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
22742         }
22743         if (filter.countActions() == 0) {
22744             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
22745             return;
22746         }
22747         if (DEBUG_PREFERRED) {
22748             Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
22749                     + userId + ":");
22750             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
22751         }
22752         synchronized (mLock) {
22753             final PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
22754             final ArrayList<PreferredActivity> existing = pir.findFilters(filter);
22755             if (removeExisting && existing != null) {
22756                 Settings.removeFilters(pir, filter, existing);
22757             }
22758             pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
22759             scheduleWritePackageRestrictionsLocked(userId);
22760         }
22761         if (!(isHomeFilter(filter) && updateDefaultHomeNotLocked(userId))) {
22762             postPreferredActivityChangedBroadcast(userId);
22763         }
22764     }
22765 
postPreferredActivityChangedBroadcast(int userId)22766     private void postPreferredActivityChangedBroadcast(int userId) {
22767         mHandler.post(() -> {
22768             final IActivityManager am = ActivityManager.getService();
22769             if (am == null) {
22770                 return;
22771             }
22772 
22773             final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
22774             intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
22775             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
22776             try {
22777                 am.broadcastIntentWithFeature(null, null, intent, null, null,
22778                         0, null, null, null, null, android.app.AppOpsManager.OP_NONE,
22779                         null, false, false, userId);
22780             } catch (RemoteException e) {
22781             }
22782         });
22783     }
22784 
22785     @Override
replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)22786     public void replacePreferredActivity(IntentFilter filter, int match,
22787             ComponentName[] set, ComponentName activity, int userId) {
22788         replacePreferredActivity(new WatchedIntentFilter(filter), match,
22789                                  set, activity, userId);
22790     }
22791 
22792     /**
22793      * Variant that takes a {@link WatchedIntentFilter}
22794      */
replacePreferredActivity(WatchedIntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)22795     public void replacePreferredActivity(WatchedIntentFilter filter, int match,
22796             ComponentName[] set, ComponentName activity, int userId) {
22797         if (filter.countActions() != 1) {
22798             throw new IllegalArgumentException(
22799                     "replacePreferredActivity expects filter to have only 1 action.");
22800         }
22801         if (filter.countDataAuthorities() != 0
22802                 || filter.countDataPaths() != 0
22803                 || filter.countDataSchemes() > 1
22804                 || filter.countDataTypes() != 0) {
22805             throw new IllegalArgumentException(
22806                     "replacePreferredActivity expects filter to have no data authorities, " +
22807                     "paths, or types; and at most one scheme.");
22808         }
22809 
22810         final int callingUid = Binder.getCallingUid();
22811         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
22812                 false /* checkShell */, "replace preferred activity");
22813         if (mContext.checkCallingOrSelfPermission(
22814                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
22815                 != PackageManager.PERMISSION_GRANTED) {
22816             synchronized (mLock) {
22817                 if (getUidTargetSdkVersionLockedLPr(callingUid)
22818                         < Build.VERSION_CODES.FROYO) {
22819                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
22820                             + Binder.getCallingUid());
22821                     return;
22822                 }
22823             }
22824             mContext.enforceCallingOrSelfPermission(
22825                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
22826         }
22827 
22828         synchronized (mLock) {
22829             final PreferredIntentResolver pir = mSettings.getPreferredActivities(userId);
22830             if (pir != null) {
22831                 // Get all of the existing entries that exactly match this filter.
22832                 final ArrayList<PreferredActivity> existing = pir.findFilters(filter);
22833                 if (existing != null && existing.size() == 1) {
22834                     final PreferredActivity cur = existing.get(0);
22835                     if (DEBUG_PREFERRED) {
22836                         Slog.i(TAG, "Checking replace of preferred:");
22837                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
22838                         if (!cur.mPref.mAlways) {
22839                             Slog.i(TAG, "  -- CUR; not mAlways!");
22840                         } else {
22841                             Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
22842                             Slog.i(TAG, "  -- CUR: mSet="
22843                                     + Arrays.toString(cur.mPref.mSetComponents));
22844                             Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
22845                             Slog.i(TAG, "  -- NEW: mMatch="
22846                                     + (match&IntentFilter.MATCH_CATEGORY_MASK));
22847                             Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
22848                             Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
22849                         }
22850                     }
22851                     if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
22852                             && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
22853                             && cur.mPref.sameSet(set)) {
22854                         // Setting the preferred activity to what it happens to be already
22855                         if (DEBUG_PREFERRED) {
22856                             Slog.i(TAG, "Replacing with same preferred activity "
22857                                     + cur.mPref.mShortComponent + " for user "
22858                                     + userId + ":");
22859                             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
22860                         }
22861                         return;
22862                     }
22863                 }
22864                 if (existing != null) {
22865                     Settings.removeFilters(pir, filter, existing);
22866                 }
22867             }
22868         }
22869         addPreferredActivity(filter, match, set, activity, true, userId,
22870                 "Replacing preferred", false);
22871     }
22872 
22873     @Override
clearPackagePreferredActivities(String packageName)22874     public void clearPackagePreferredActivities(String packageName) {
22875         final int callingUid = Binder.getCallingUid();
22876         if (getInstantAppPackageName(callingUid) != null) {
22877             return;
22878         }
22879         // writer
22880         synchronized (mLock) {
22881             AndroidPackage pkg = mPackages.get(packageName);
22882             if (pkg == null || !isCallerSameApp(packageName, callingUid)) {
22883                 if (mContext.checkCallingOrSelfPermission(
22884                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
22885                         != PackageManager.PERMISSION_GRANTED) {
22886                     if (getUidTargetSdkVersionLockedLPr(callingUid)
22887                             < Build.VERSION_CODES.FROYO) {
22888                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
22889                                 + callingUid);
22890                         return;
22891                     }
22892                     mContext.enforceCallingOrSelfPermission(
22893                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
22894                 }
22895             }
22896             final PackageSetting ps = mSettings.getPackageLPr(packageName);
22897             if (ps != null
22898                     && shouldFilterApplicationLocked(
22899                             ps, callingUid, UserHandle.getUserId(callingUid))) {
22900                 return;
22901             }
22902         }
22903         int callingUserId = UserHandle.getCallingUserId();
22904         clearPackagePreferredActivities(packageName, callingUserId);
22905     }
22906 
22907     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
clearPackagePreferredActivities(String packageName, int userId)22908     private void clearPackagePreferredActivities(String packageName, int userId) {
22909         final SparseBooleanArray changedUsers = new SparseBooleanArray();
22910         synchronized (mLock) {
22911             clearPackagePreferredActivitiesLPw(packageName, changedUsers, userId);
22912         }
22913         if (changedUsers.size() > 0) {
22914             updateDefaultHomeNotLocked(changedUsers);
22915             postPreferredActivityChangedBroadcast(userId);
22916             synchronized (mLock) {
22917                 scheduleWritePackageRestrictionsLocked(userId);
22918             }
22919         }
22920     }
22921 
22922     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
22923     @GuardedBy("mLock")
clearPackagePreferredActivitiesLPw(String packageName, @NonNull SparseBooleanArray outUserChanged, int userId)22924     private void clearPackagePreferredActivitiesLPw(String packageName,
22925             @NonNull SparseBooleanArray outUserChanged, int userId) {
22926         mSettings.clearPackagePreferredActivities(packageName, outUserChanged, userId);
22927     }
22928 
restorePermissionsAndUpdateRolesForNewUserInstall(String packageName, int installReason, @UserIdInt int userId)22929     private void restorePermissionsAndUpdateRolesForNewUserInstall(String packageName,
22930             int installReason, @UserIdInt int userId) {
22931         // We may also need to apply pending (restored) runtime permission grants
22932         // within these users.
22933         mPermissionManager.restoreDelayedRuntimePermissions(packageName, userId);
22934 
22935         // Persistent preferred activity might have came into effect due to this
22936         // install.
22937         updateDefaultHomeNotLocked(userId);
22938     }
22939 
22940     @Override
resetApplicationPreferences(int userId)22941     public void resetApplicationPreferences(int userId) {
22942         mContext.enforceCallingOrSelfPermission(
22943                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
22944         final long identity = Binder.clearCallingIdentity();
22945         // writer
22946         try {
22947             final SparseBooleanArray changedUsers = new SparseBooleanArray();
22948             synchronized (mLock) {
22949                 clearPackagePreferredActivitiesLPw(null, changedUsers, userId);
22950             }
22951             if (changedUsers.size() > 0) {
22952                 postPreferredActivityChangedBroadcast(userId);
22953             }
22954             synchronized (mLock) {
22955                 mSettings.applyDefaultPreferredAppsLPw(userId);
22956                 mDomainVerificationManager.clearUser(userId);
22957                 final int numPackages = mPackages.size();
22958                 for (int i = 0; i < numPackages; i++) {
22959                     final AndroidPackage pkg = mPackages.valueAt(i);
22960                     mPermissionManager.resetRuntimePermissions(pkg, userId);
22961                 }
22962             }
22963             updateDefaultHomeNotLocked(userId);
22964             resetNetworkPolicies(userId);
22965             synchronized (mLock) {
22966                 scheduleWritePackageRestrictionsLocked(userId);
22967             }
22968         } finally {
22969             Binder.restoreCallingIdentity(identity);
22970         }
22971     }
22972 
22973     @Override
getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)22974     public int getPreferredActivities(List<IntentFilter> outFilters,
22975             List<ComponentName> outActivities, String packageName) {
22976         List<WatchedIntentFilter> temp =
22977                 WatchedIntentFilter.toWatchedIntentFilterList(outFilters);
22978         final int result = getPreferredActivitiesInternal(
22979                 temp, outActivities, packageName);
22980         outFilters.clear();
22981         for (int i = 0; i < temp.size(); i++) {
22982             outFilters.add(temp.get(i).getIntentFilter());
22983         }
22984         return result;
22985     }
22986 
22987     /**
22988      * Variant that takes a {@link WatchedIntentFilter}
22989      */
getPreferredActivitiesInternal(List<WatchedIntentFilter> outFilters, List<ComponentName> outActivities, String packageName)22990     public int getPreferredActivitiesInternal(List<WatchedIntentFilter> outFilters,
22991             List<ComponentName> outActivities, String packageName) {
22992         final int callingUid = Binder.getCallingUid();
22993         if (getInstantAppPackageName(callingUid) != null) {
22994             return 0;
22995         }
22996         int num = 0;
22997         final int userId = UserHandle.getCallingUserId();
22998         // reader
22999         synchronized (mLock) {
23000             PreferredIntentResolver pir = mSettings.getPreferredActivities(userId);
23001             if (pir != null) {
23002                 final Iterator<PreferredActivity> it = pir.filterIterator();
23003                 while (it.hasNext()) {
23004                     final PreferredActivity pa = it.next();
23005                     final String prefPackageName = pa.mPref.mComponent.getPackageName();
23006                     if (packageName == null
23007                             || (prefPackageName.equals(packageName) && pa.mPref.mAlways)) {
23008                         if (shouldFilterApplicationLocked(
23009                                 mSettings.getPackageLPr(prefPackageName), callingUid, userId)) {
23010                             continue;
23011                         }
23012                         if (outFilters != null) {
23013                             outFilters.add(new WatchedIntentFilter(pa.getIntentFilter()));
23014                         }
23015                         if (outActivities != null) {
23016                             outActivities.add(pa.mPref.mComponent);
23017                         }
23018                     }
23019                 }
23020             }
23021         }
23022 
23023         return num;
23024     }
23025 
23026     @Override
addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, int userId)23027     public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
23028             int userId) {
23029         addPersistentPreferredActivity(new WatchedIntentFilter(filter), activity, userId);
23030     }
23031 
23032     /**
23033      * Variant that takes a {@link WatchedIntentFilter}
23034      */
addPersistentPreferredActivity(WatchedIntentFilter filter, ComponentName activity, int userId)23035     public void addPersistentPreferredActivity(WatchedIntentFilter filter, ComponentName activity,
23036             int userId) {
23037         int callingUid = Binder.getCallingUid();
23038         if (callingUid != Process.SYSTEM_UID) {
23039             throw new SecurityException(
23040                     "addPersistentPreferredActivity can only be run by the system");
23041         }
23042         if (filter.countActions() == 0) {
23043             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
23044             return;
23045         }
23046         if (DEBUG_PREFERRED) {
23047             Slog.i(TAG, "Adding persistent preferred activity " + activity
23048                     + " for user " + userId + ":");
23049             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
23050         }
23051         synchronized (mLock) {
23052             mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
23053                     new PersistentPreferredActivity(filter, activity, true));
23054             scheduleWritePackageRestrictionsLocked(userId);
23055         }
23056         if (isHomeFilter(filter)) {
23057             updateDefaultHomeNotLocked(userId);
23058         }
23059         postPreferredActivityChangedBroadcast(userId);
23060     }
23061 
23062     @Override
clearPackagePersistentPreferredActivities(String packageName, int userId)23063     public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
23064         int callingUid = Binder.getCallingUid();
23065         if (callingUid != Process.SYSTEM_UID) {
23066             throw new SecurityException(
23067                     "clearPackagePersistentPreferredActivities can only be run by the system");
23068         }
23069         boolean changed = false;
23070         synchronized (mLock) {
23071             changed = mSettings.clearPackagePersistentPreferredActivities(packageName, userId);
23072         }
23073         if (changed) {
23074             updateDefaultHomeNotLocked(userId);
23075             postPreferredActivityChangedBroadcast(userId);
23076             synchronized (mLock) {
23077                 scheduleWritePackageRestrictionsLocked(userId);
23078             }
23079         }
23080     }
23081 
23082     /**
23083      * Common machinery for picking apart a restored XML blob and passing
23084      * it to a caller-supplied functor to be applied to the running system.
23085      */
restoreFromXml(TypedXmlPullParser parser, int userId, String expectedStartTag, BlobXmlRestorer functor)23086     private void restoreFromXml(TypedXmlPullParser parser, int userId,
23087             String expectedStartTag, BlobXmlRestorer functor)
23088             throws IOException, XmlPullParserException {
23089         int type;
23090         while ((type = parser.next()) != XmlPullParser.START_TAG
23091                 && type != XmlPullParser.END_DOCUMENT) {
23092         }
23093         if (type != XmlPullParser.START_TAG) {
23094             // oops didn't find a start tag?!
23095             if (DEBUG_BACKUP) {
23096                 Slog.e(TAG, "Didn't find start tag during restore");
23097             }
23098             return;
23099         }
23100         // this is supposed to be TAG_PREFERRED_BACKUP
23101         if (!expectedStartTag.equals(parser.getName())) {
23102             if (DEBUG_BACKUP) {
23103                 Slog.e(TAG, "Found unexpected tag " + parser.getName());
23104             }
23105             return;
23106         }
23107 
23108         // skip interfering stuff, then we're aligned with the backing implementation
23109         while ((type = parser.next()) == XmlPullParser.TEXT) { }
23110         functor.apply(parser, userId);
23111     }
23112 
23113     private interface BlobXmlRestorer {
apply(TypedXmlPullParser parser, int userId)23114         void apply(TypedXmlPullParser parser, int userId)
23115                 throws IOException, XmlPullParserException;
23116     }
23117 
23118     /**
23119      * Non-Binder method, support for the backup/restore mechanism: write the
23120      * full set of preferred activities in its canonical XML format.  Returns the
23121      * XML output as a byte array, or null if there is none.
23122      */
23123     @Override
getPreferredActivityBackup(int userId)23124     public byte[] getPreferredActivityBackup(int userId) {
23125         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
23126             throw new SecurityException("Only the system may call getPreferredActivityBackup()");
23127         }
23128 
23129         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
23130         try {
23131             final TypedXmlSerializer serializer = Xml.newFastSerializer();
23132             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
23133             serializer.startDocument(null, true);
23134             serializer.startTag(null, TAG_PREFERRED_BACKUP);
23135 
23136             synchronized (mLock) {
23137                 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
23138             }
23139 
23140             serializer.endTag(null, TAG_PREFERRED_BACKUP);
23141             serializer.endDocument();
23142             serializer.flush();
23143         } catch (Exception e) {
23144             if (DEBUG_BACKUP) {
23145                 Slog.e(TAG, "Unable to write preferred activities for backup", e);
23146             }
23147             return null;
23148         }
23149 
23150         return dataStream.toByteArray();
23151     }
23152 
23153     @Override
restorePreferredActivities(byte[] backup, int userId)23154     public void restorePreferredActivities(byte[] backup, int userId) {
23155         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
23156             throw new SecurityException("Only the system may call restorePreferredActivities()");
23157         }
23158 
23159         try {
23160             final TypedXmlPullParser parser = Xml.newFastPullParser();
23161             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
23162             restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
23163                     (readParser, readUserId) -> {
23164                         synchronized (mLock) {
23165                             mSettings.readPreferredActivitiesLPw(readParser, readUserId);
23166                         }
23167                         updateDefaultHomeNotLocked(readUserId);
23168                     });
23169         } catch (Exception e) {
23170             if (DEBUG_BACKUP) {
23171                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
23172             }
23173         }
23174     }
23175 
23176     /**
23177      * Non-Binder method, support for the backup/restore mechanism: write the
23178      * default browser (etc) settings in its canonical XML format.  Returns the default
23179      * browser XML representation as a byte array, or null if there is none.
23180      */
23181     @Override
getDefaultAppsBackup(int userId)23182     public byte[] getDefaultAppsBackup(int userId) {
23183         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
23184             throw new SecurityException("Only the system may call getDefaultAppsBackup()");
23185         }
23186 
23187         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
23188         try {
23189             final TypedXmlSerializer serializer = Xml.newFastSerializer();
23190             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
23191             serializer.startDocument(null, true);
23192             serializer.startTag(null, TAG_DEFAULT_APPS);
23193 
23194             synchronized (mLock) {
23195                 mSettings.writeDefaultAppsLPr(serializer, userId);
23196             }
23197 
23198             serializer.endTag(null, TAG_DEFAULT_APPS);
23199             serializer.endDocument();
23200             serializer.flush();
23201         } catch (Exception e) {
23202             if (DEBUG_BACKUP) {
23203                 Slog.e(TAG, "Unable to write default apps for backup", e);
23204             }
23205             return null;
23206         }
23207 
23208         return dataStream.toByteArray();
23209     }
23210 
23211     @Override
restoreDefaultApps(byte[] backup, int userId)23212     public void restoreDefaultApps(byte[] backup, int userId) {
23213         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
23214             throw new SecurityException("Only the system may call restoreDefaultApps()");
23215         }
23216 
23217         try {
23218             final TypedXmlPullParser parser = Xml.newFastPullParser();
23219             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
23220             restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
23221                     (parser1, userId1) -> {
23222                         final String defaultBrowser;
23223                         synchronized (mLock) {
23224                             mSettings.readDefaultAppsLPw(parser1, userId1);
23225                             defaultBrowser = mSettings.removeDefaultBrowserPackageNameLPw(userId1);
23226                         }
23227                         if (defaultBrowser != null) {
23228                             mDefaultAppProvider.setDefaultBrowser(defaultBrowser, false, userId1);
23229                         }
23230                     });
23231         } catch (Exception e) {
23232             if (DEBUG_BACKUP) {
23233                 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
23234             }
23235         }
23236     }
23237 
23238     @Override
getDomainVerificationBackup(int userId)23239     public byte[] getDomainVerificationBackup(int userId) {
23240         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
23241             throw new SecurityException("Only the system may call getDomainVerificationBackup()");
23242         }
23243 
23244         try {
23245             try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
23246                 TypedXmlSerializer serializer = Xml.resolveSerializer(output);
23247                 mDomainVerificationManager.writeSettings(serializer, true, userId);
23248                 return output.toByteArray();
23249             }
23250         } catch (Exception e) {
23251             if (DEBUG_BACKUP) {
23252                 Slog.e(TAG, "Unable to write domain verification for backup", e);
23253             }
23254             return null;
23255         }
23256     }
23257 
23258     @Override
restoreDomainVerification(byte[] backup, int userId)23259     public void restoreDomainVerification(byte[] backup, int userId) {
23260         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
23261             throw new SecurityException("Only the system may call restorePreferredActivities()");
23262         }
23263 
23264         try {
23265             ByteArrayInputStream input = new ByteArrayInputStream(backup);
23266             TypedXmlPullParser parser = Xml.resolvePullParser(input);
23267 
23268             // User ID input isn't necessary here as it assumes the user integers match and that
23269             // the only states inside the backup XML are for the target user.
23270             mDomainVerificationManager.restoreSettings(parser);
23271             input.close();
23272         } catch (Exception e) {
23273             if (DEBUG_BACKUP) {
23274                 Slog.e(TAG, "Exception restoring domain verification: " + e.getMessage());
23275             }
23276         }
23277     }
23278 
23279     @Override
addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, int sourceUserId, int targetUserId, int flags)23280     public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
23281             int sourceUserId, int targetUserId, int flags) {
23282         addCrossProfileIntentFilter(new WatchedIntentFilter(intentFilter), ownerPackage,
23283                                     sourceUserId, targetUserId, flags);
23284     }
23285 
23286     /**
23287      * Variant that takes a {@link WatchedIntentFilter}
23288      */
addCrossProfileIntentFilter(WatchedIntentFilter intentFilter, String ownerPackage, int sourceUserId, int targetUserId, int flags)23289     public void addCrossProfileIntentFilter(WatchedIntentFilter intentFilter, String ownerPackage,
23290             int sourceUserId, int targetUserId, int flags) {
23291         mContext.enforceCallingOrSelfPermission(
23292                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
23293         int callingUid = Binder.getCallingUid();
23294         enforceOwnerRights(ownerPackage, callingUid);
23295         PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
23296                 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
23297         if (intentFilter.countActions() == 0) {
23298             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
23299             return;
23300         }
23301         synchronized (mLock) {
23302             CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
23303                     ownerPackage, targetUserId, flags);
23304             CrossProfileIntentResolver resolver =
23305                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
23306             ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
23307             // We have all those whose filter is equal. Now checking if the rest is equal as well.
23308             if (existing != null) {
23309                 int size = existing.size();
23310                 for (int i = 0; i < size; i++) {
23311                     if (newFilter.equalsIgnoreFilter(existing.get(i))) {
23312                         return;
23313                     }
23314                 }
23315             }
23316             resolver.addFilter(newFilter);
23317             scheduleWritePackageRestrictionsLocked(sourceUserId);
23318         }
23319     }
23320 
23321     @Override
clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage)23322     public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
23323         mContext.enforceCallingOrSelfPermission(
23324                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
23325         final int callingUid = Binder.getCallingUid();
23326         enforceOwnerRights(ownerPackage, callingUid);
23327         PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
23328                 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
23329         synchronized (mLock) {
23330             CrossProfileIntentResolver resolver =
23331                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
23332             ArraySet<CrossProfileIntentFilter> set =
23333                     new ArraySet<>(resolver.filterSet());
23334             for (CrossProfileIntentFilter filter : set) {
23335                 if (filter.getOwnerPackage().equals(ownerPackage)) {
23336                     resolver.removeFilter(filter);
23337                 }
23338             }
23339             scheduleWritePackageRestrictionsLocked(sourceUserId);
23340         }
23341     }
23342 
23343     // Enforcing that callingUid is owning pkg on userId
enforceOwnerRights(String pkg, int callingUid)23344     private void enforceOwnerRights(String pkg, int callingUid) {
23345         // The system owns everything.
23346         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
23347             return;
23348         }
23349         final String[] callerPackageNames = getPackagesForUid(callingUid);
23350         if (!ArrayUtils.contains(callerPackageNames, pkg)) {
23351             throw new SecurityException("Calling uid " + callingUid
23352                     + " does not own package " + pkg);
23353         }
23354         final int callingUserId = UserHandle.getUserId(callingUid);
23355         PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
23356         if (pi == null) {
23357             throw new IllegalArgumentException("Unknown package " + pkg + " on user "
23358                     + callingUserId);
23359         }
23360     }
23361 
23362     @Override
getHomeActivities(List<ResolveInfo> allHomeCandidates)23363     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
23364         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23365             return null;
23366         }
23367         return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
23368     }
23369 
23370     /**
23371      * Send a {@code PackageInstaller.ACTION_SESSION_UPDATED} broadcast intent, containing
23372      * the {@code sessionInfo} in the extra field {@code PackageInstaller.EXTRA_SESSION}.
23373      */
sendSessionUpdatedBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId)23374     public void sendSessionUpdatedBroadcast(PackageInstaller.SessionInfo sessionInfo,
23375             int userId) {
23376         if (TextUtils.isEmpty(sessionInfo.installerPackageName)) {
23377             return;
23378         }
23379         Intent sessionUpdatedIntent = new Intent(PackageInstaller.ACTION_SESSION_UPDATED)
23380                 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
23381                 .setPackage(sessionInfo.installerPackageName);
23382         mContext.sendBroadcastAsUser(sessionUpdatedIntent, UserHandle.of(userId));
23383     }
23384 
sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId)23385     public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
23386         UserManagerService ums = UserManagerService.getInstance();
23387         if (ums != null && !sessionInfo.isStaged()) {
23388             final UserInfo parent = ums.getProfileParent(userId);
23389             final int launcherUid = (parent != null) ? parent.id : userId;
23390             final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
23391             if (launcherComponent != null) {
23392                 Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
23393                         .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
23394                         .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
23395                         .setPackage(launcherComponent.getPackageName());
23396                 mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
23397             }
23398             // TODO(b/122900055) Change/Remove this and replace with new permission role.
23399             if (mAppPredictionServicePackage != null) {
23400                 Intent predictorIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
23401                         .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
23402                         .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
23403                         .setPackage(mAppPredictionServicePackage);
23404                 mContext.sendBroadcastAsUser(predictorIntent, UserHandle.of(launcherUid));
23405             }
23406         }
23407     }
23408 
23409     /**
23410      * Report the 'Home' activity which is currently set as "always use this one". If non is set
23411      * then reports the most likely home activity or null if there are more than one.
23412      */
getDefaultHomeActivity(int userId)23413     private ComponentName getDefaultHomeActivity(int userId) {
23414         return mComputer.getDefaultHomeActivity(userId);
23415     }
23416 
getHomeIntent()23417     private Intent getHomeIntent() {
23418         return mComputer.getHomeIntent();
23419     }
23420 
getHomeFilter()23421     private WatchedIntentFilter getHomeFilter() {
23422         WatchedIntentFilter filter = new WatchedIntentFilter(Intent.ACTION_MAIN);
23423         filter.addCategory(Intent.CATEGORY_HOME);
23424         filter.addCategory(Intent.CATEGORY_DEFAULT);
23425         return filter;
23426     }
23427 
isHomeFilter(@onNull WatchedIntentFilter filter)23428     private boolean isHomeFilter(@NonNull WatchedIntentFilter filter) {
23429         return filter.hasAction(Intent.ACTION_MAIN) && filter.hasCategory(Intent.CATEGORY_HOME)
23430                 && filter.hasCategory(CATEGORY_DEFAULT);
23431     }
23432 
getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId)23433     ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23434             int userId) {
23435         return mComputer.getHomeActivitiesAsUser(allHomeCandidates,
23436                 userId);
23437     }
23438 
23439     /** <b>must not hold {@link #mLock}</b> */
updateDefaultHomeNotLocked(SparseBooleanArray userIds)23440     private void updateDefaultHomeNotLocked(SparseBooleanArray userIds) {
23441         if (Thread.holdsLock(mLock)) {
23442             Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
23443                     + " is holding mLock", new Throwable());
23444         }
23445         for (int i = userIds.size() - 1; i >= 0; --i) {
23446             final int userId = userIds.keyAt(i);
23447             updateDefaultHomeNotLocked(userId);
23448         }
23449     }
23450 
23451     /**
23452      * <b>must not hold {@link #mLock}</b>
23453      *
23454      * @return Whether the ACTION_PREFERRED_ACTIVITY_CHANGED broadcast has been scheduled.
23455      */
updateDefaultHomeNotLocked(int userId)23456     private boolean updateDefaultHomeNotLocked(int userId) {
23457         if (Thread.holdsLock(mLock)) {
23458             Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
23459                     + " is holding mLock", new Throwable());
23460         }
23461         if (!mSystemReady) {
23462             // We might get called before system is ready because of package changes etc, but
23463             // finding preferred activity depends on settings provider, so we ignore the update
23464             // before that.
23465             return false;
23466         }
23467         final Intent intent = getHomeIntent();
23468         final List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
23469                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, userId);
23470         final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(
23471                 intent, null, 0, resolveInfos, 0, true, false, false, userId);
23472         final String packageName = preferredResolveInfo != null
23473                 && preferredResolveInfo.activityInfo != null
23474                 ? preferredResolveInfo.activityInfo.packageName : null;
23475         final String currentPackageName = mDefaultAppProvider.getDefaultHome(userId);
23476         if (TextUtils.equals(currentPackageName, packageName)) {
23477             return false;
23478         }
23479         final String[] callingPackages = getPackagesForUid(Binder.getCallingUid());
23480         if (callingPackages != null && ArrayUtils.contains(callingPackages,
23481                 mRequiredPermissionControllerPackage)) {
23482             // PermissionController manages default home directly.
23483             return false;
23484         }
23485 
23486         if (packageName == null) {
23487             // Keep the default home package in RoleManager.
23488             return false;
23489         }
23490         return mDefaultAppProvider.setDefaultHome(packageName, userId, mContext.getMainExecutor(),
23491                 successful -> {
23492                     if (successful) {
23493                         postPreferredActivityChangedBroadcast(userId);
23494                     }
23495                 });
23496     }
23497 
23498     @Override
23499     public void setHomeActivity(ComponentName comp, int userId) {
23500         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23501             return;
23502         }
23503         ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
23504         getHomeActivitiesAsUser(homeActivities, userId);
23505 
23506         boolean found = false;
23507 
23508         final int size = homeActivities.size();
23509         final ComponentName[] set = new ComponentName[size];
23510         for (int i = 0; i < size; i++) {
23511             final ResolveInfo candidate = homeActivities.get(i);
23512             final ActivityInfo info = candidate.activityInfo;
23513             final ComponentName activityName = new ComponentName(info.packageName, info.name);
23514             set[i] = activityName;
23515             if (!found && activityName.equals(comp)) {
23516                 found = true;
23517             }
23518         }
23519         if (!found) {
23520             throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
23521                     + userId);
23522         }
23523         replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
23524                 set, comp, userId);
23525     }
23526 
23527     private @Nullable String getSetupWizardPackageNameImpl() {
23528         final Intent intent = new Intent(Intent.ACTION_MAIN);
23529         intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
23530 
23531         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
23532                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
23533                         | MATCH_DISABLED_COMPONENTS,
23534                 UserHandle.myUserId());
23535         if (matches.size() == 1) {
23536             return matches.get(0).getComponentInfo().packageName;
23537         } else {
23538             Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
23539                     + ": matches=" + matches);
23540             return null;
23541         }
23542     }
23543 
23544     private @Nullable String getStorageManagerPackageName() {
23545         final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
23546 
23547         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
23548                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
23549                         | MATCH_DISABLED_COMPONENTS,
23550                 UserHandle.myUserId());
23551         if (matches.size() == 1) {
23552             return matches.get(0).getComponentInfo().packageName;
23553         } else {
23554             Slog.w(TAG, "There should probably be exactly one storage manager; found "
23555                     + matches.size() + ": matches=" + matches);
23556             return null;
23557         }
23558     }
23559 
23560     @Override
23561     public String getDefaultTextClassifierPackageName() {
23562         return ensureSystemPackageName(
23563                 mContext.getString(R.string.config_servicesExtensionPackage));
23564     }
23565 
23566     @Override
23567     public String getSystemTextClassifierPackageName() {
23568         return ensureSystemPackageName(
23569                 mContext.getString(R.string.config_defaultTextClassifierPackage));
23570     }
23571 
23572     @Override
23573     public @Nullable String getAttentionServicePackageName() {
23574         return ensureSystemPackageName(
23575                 getPackageFromComponentString(R.string.config_defaultAttentionService));
23576     }
23577 
23578     @Override
23579     public @Nullable String getRotationResolverPackageName() {
23580         return ensureSystemPackageName(
23581                 getPackageFromComponentString(R.string.config_defaultRotationResolverService));
23582     }
23583 
23584     private @Nullable String getDocumenterPackageName() {
23585         final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
23586         intent.addCategory(Intent.CATEGORY_OPENABLE);
23587         intent.setType("*/*");
23588         final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23589 
23590         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, resolvedType,
23591                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
23592                         | MATCH_DISABLED_COMPONENTS,
23593                 UserHandle.myUserId());
23594         if (matches.size() == 1) {
23595             return matches.get(0).getComponentInfo().packageName;
23596         } else {
23597             Slog.e(TAG, "There should probably be exactly one documenter; found "
23598                     + matches.size() + ": matches=" + matches);
23599             return null;
23600         }
23601     }
23602 
23603     @Nullable
23604     private String getDeviceConfiguratorPackageName() {
23605         return ensureSystemPackageName(mContext.getString(
23606                 R.string.config_deviceConfiguratorPackageName));
23607     }
23608 
23609     @Override
23610     public String getWellbeingPackageName() {
23611         final long identity = Binder.clearCallingIdentity();
23612         try {
23613             return CollectionUtils.firstOrNull(
23614                     mContext.getSystemService(RoleManager.class).getRoleHolders(
23615                             RoleManager.ROLE_SYSTEM_WELLBEING));
23616         } finally {
23617             Binder.restoreCallingIdentity(identity);
23618         }
23619     }
23620 
23621     @Override
23622     public String getAppPredictionServicePackageName() {
23623         return ensureSystemPackageName(
23624                 getPackageFromComponentString(R.string.config_defaultAppPredictionService));
23625     }
23626 
23627     @Override
23628     public String getSystemCaptionsServicePackageName() {
23629         return ensureSystemPackageName(
23630                 getPackageFromComponentString(R.string.config_defaultSystemCaptionsService));
23631     }
23632 
23633     @Override
23634     public String getSetupWizardPackageName() {
23635         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
23636             throw new SecurityException("Non-system caller");
23637         }
23638         return mPmInternal.getSetupWizardPackageName();
23639     }
23640 
23641     public String getIncidentReportApproverPackageName() {
23642         return ensureSystemPackageName(mContext.getString(
23643                 R.string.config_incidentReportApproverPackage));
23644     }
23645 
23646     @Override
23647     public String getContentCaptureServicePackageName() {
23648         return ensureSystemPackageName(
23649                 getPackageFromComponentString(R.string.config_defaultContentCaptureService));
23650     }
23651 
23652     public String getOverlayConfigSignaturePackageName() {
23653         return ensureSystemPackageName(mInjector.getSystemConfig()
23654                 .getOverlayConfigSignaturePackage());
23655     }
23656 
23657     @Nullable
23658     private String getRetailDemoPackageName() {
23659         final String predefinedPkgName = mContext.getString(R.string.config_retailDemoPackage);
23660         final String predefinedSignature = mContext.getString(
23661                 R.string.config_retailDemoPackageSignature);
23662 
23663         if (TextUtils.isEmpty(predefinedPkgName) || TextUtils.isEmpty(predefinedSignature)) {
23664             return null;
23665         }
23666 
23667         final AndroidPackage androidPkg = mPackages.get(predefinedPkgName);
23668         if (androidPkg != null) {
23669             final SigningDetails signingDetail = androidPkg.getSigningDetails();
23670             if (signingDetail != null && signingDetail.signatures != null) {
23671                 try {
23672                     final MessageDigest msgDigest = MessageDigest.getInstance("SHA-256");
23673                     for (Signature signature : signingDetail.signatures) {
23674                         if (TextUtils.equals(predefinedSignature,
23675                                 HexEncoding.encodeToString(msgDigest.digest(
23676                                         signature.toByteArray()), false))) {
23677                             return predefinedPkgName;
23678                         }
23679                     }
23680                 } catch (NoSuchAlgorithmException e) {
23681                     Slog.e(
23682                             TAG,
23683                             "Unable to verify signatures as getting the retail demo package name",
23684                             e);
23685                 }
23686             }
23687         }
23688 
23689         return null;
23690     }
23691 
23692     @Nullable
23693     private String getRecentsPackageName() {
23694         return ensureSystemPackageName(
23695                 getPackageFromComponentString(R.string.config_recentsComponentName));
23696 
23697     }
23698 
23699     @Nullable
23700     private String getPackageFromComponentString(@StringRes int stringResId) {
23701         final String componentString = mContext.getString(stringResId);
23702         if (TextUtils.isEmpty(componentString)) {
23703             return null;
23704         }
23705         final ComponentName component = ComponentName.unflattenFromString(componentString);
23706         if (component == null) {
23707             return null;
23708         }
23709         return component.getPackageName();
23710     }
23711 
23712     @Nullable
23713     private String ensureSystemPackageName(@Nullable String packageName) {
23714         if (packageName == null) {
23715             return null;
23716         }
23717         final long token = Binder.clearCallingIdentity();
23718         try {
23719             if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) {
23720                 PackageInfo packageInfo = getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM);
23721                 if (packageInfo != null) {
23722                     EventLog.writeEvent(0x534e4554, "145981139", packageInfo.applicationInfo.uid,
23723                             "");
23724                 }
23725                 return null;
23726             }
23727         } finally {
23728             Binder.restoreCallingIdentity(token);
23729         }
23730         return packageName;
23731     }
23732 
23733     @Nullable
23734     private String[] ensureSystemPackageNames(@Nullable String[] packageNames) {
23735         if (packageNames == null) {
23736             return null;
23737         }
23738         final int packageNamesLength = packageNames.length;
23739         for (int i = 0; i < packageNamesLength; i++) {
23740             packageNames[i] = ensureSystemPackageName(packageNames[i]);
23741         }
23742         return ArrayUtils.filterNotNull(packageNames, String[]::new);
23743     }
23744 
23745     @Override
23746     public void setApplicationEnabledSetting(String appPackageName,
23747             int newState, int flags, int userId, String callingPackage) {
23748         if (!mUserManager.exists(userId)) return;
23749         if (callingPackage == null) {
23750             callingPackage = Integer.toString(Binder.getCallingUid());
23751         }
23752         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
23753     }
23754 
23755     @Override
23756     public void setUpdateAvailable(String packageName, boolean updateAvailable) {
23757         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
23758         synchronized (mLock) {
23759             final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
23760             if (pkgSetting != null) {
23761                 pkgSetting.setUpdateAvailable(updateAvailable);
23762             }
23763         }
23764     }
23765 
23766     @Override
23767     public void overrideLabelAndIcon(@NonNull ComponentName componentName,
23768             @NonNull String nonLocalizedLabel, int icon, int userId) {
23769         if (TextUtils.isEmpty(nonLocalizedLabel)) {
23770             throw new IllegalArgumentException("Override label should be a valid String");
23771         }
23772         updateComponentLabelIcon(componentName, nonLocalizedLabel, icon, userId);
23773     }
23774 
23775     @Override
23776     public void restoreLabelAndIcon(@NonNull ComponentName componentName, int userId) {
23777         updateComponentLabelIcon(componentName, null, null, userId);
23778     }
23779 
23780     @VisibleForTesting(visibility = Visibility.PRIVATE)
23781     public void updateComponentLabelIcon(/*@NonNull*/ ComponentName componentName,
23782             @Nullable String nonLocalizedLabel, @Nullable Integer icon, int userId) {
23783         if (componentName == null) {
23784             throw new IllegalArgumentException("Must specify a component");
23785         }
23786 
23787         int callingUid = Binder.getCallingUid();
23788 
23789         String componentPkgName = componentName.getPackageName();
23790         int componentUid = getPackageUid(componentPkgName, 0, userId);
23791         if (!UserHandle.isSameApp(callingUid, componentUid)) {
23792             throw new SecurityException("The calling UID (" + callingUid + ")"
23793                     + " does not match the target UID");
23794         }
23795 
23796         String allowedCallerPkg = mContext.getString(R.string.config_overrideComponentUiPackage);
23797         if (TextUtils.isEmpty(allowedCallerPkg)) {
23798             throw new SecurityException(
23799                     "There is no package defined as allowed to change a component's label or icon");
23800         }
23801 
23802         int allowedCallerUid = getPackageUid(allowedCallerPkg, PackageManager.MATCH_SYSTEM_ONLY,
23803                 userId);
23804         if (allowedCallerUid == -1 || !UserHandle.isSameApp(callingUid, allowedCallerUid)) {
23805             throw new SecurityException("The calling UID (" + callingUid + ")"
23806                     + " is not allowed to change a component's label or icon");
23807         }
23808 
23809         synchronized (mLock) {
23810             AndroidPackage pkg = mPackages.get(componentPkgName);
23811             PackageSetting pkgSetting = getPackageSetting(componentPkgName);
23812             if (pkg == null || pkgSetting == null
23813                     || (!pkg.isSystem() && !pkgSetting.getPkgState().isUpdatedSystemApp())) {
23814                 throw new SecurityException(
23815                         "Changing the label is not allowed for " + componentName);
23816             }
23817 
23818             if (!mComponentResolver.componentExists(componentName)) {
23819                 throw new IllegalArgumentException("Component " + componentName + " not found");
23820             }
23821 
23822             if (!pkgSetting.overrideNonLocalizedLabelAndIcon(componentName, nonLocalizedLabel,
23823                     icon, userId)) {
23824                 // Nothing changed
23825                 return;
23826             }
23827         }
23828 
23829         ArrayList<String> components = mPendingBroadcasts.get(userId, componentPkgName);
23830         if (components == null) {
23831             components = new ArrayList<>();
23832             mPendingBroadcasts.put(userId, componentPkgName, components);
23833         }
23834 
23835         String className = componentName.getClassName();
23836         if (!components.contains(className)) {
23837             components.add(className);
23838         }
23839 
23840         if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
23841             mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
23842         }
23843     }
23844 
23845     @Override
23846     public void setComponentEnabledSetting(ComponentName componentName,
23847             int newState, int flags, int userId) {
23848         if (!mUserManager.exists(userId)) return;
23849         setEnabledSetting(componentName.getPackageName(),
23850                 componentName.getClassName(), newState, flags, userId, null);
23851     }
23852 
23853     private void setEnabledSetting(final String packageName, String className, int newState,
23854             final int flags, int userId, String callingPackage) {
23855         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
23856               || newState == COMPONENT_ENABLED_STATE_ENABLED
23857               || newState == COMPONENT_ENABLED_STATE_DISABLED
23858               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
23859               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
23860             throw new IllegalArgumentException("Invalid new component state: "
23861                     + newState);
23862         }
23863         PackageSetting pkgSetting;
23864         final int callingUid = Binder.getCallingUid();
23865         final int permission;
23866         if (callingUid == Process.SYSTEM_UID) {
23867             permission = PackageManager.PERMISSION_GRANTED;
23868         } else {
23869             permission = mContext.checkCallingOrSelfPermission(
23870                     android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
23871         }
23872         enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
23873                 true /* checkShell */, "set enabled");
23874         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
23875         boolean sendNow = false;
23876         boolean isApp = (className == null);
23877         final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
23878         String componentName = isApp ? packageName : className;
23879         ArrayList<String> components;
23880 
23881         // reader
23882         synchronized (mLock) {
23883             pkgSetting = mSettings.getPackageLPr(packageName);
23884             if (pkgSetting == null) {
23885                 if (!isCallerInstantApp) {
23886                     if (className == null) {
23887                         throw new IllegalArgumentException("Unknown package: " + packageName);
23888                     }
23889                     throw new IllegalArgumentException(
23890                             "Unknown component: " + packageName + "/" + className);
23891                 } else {
23892                     // throw SecurityException to prevent leaking package information
23893                     throw new SecurityException(
23894                             "Attempt to change component state; "
23895                             + "pid=" + Binder.getCallingPid()
23896                             + ", uid=" + callingUid
23897                             + (className == null
23898                                     ? ", package=" + packageName
23899                                     : ", component=" + packageName + "/" + className));
23900                 }
23901             }
23902         }
23903 
23904         // Limit who can change which apps
23905         if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
23906             // Don't allow apps that don't have permission to modify other apps
23907             final boolean filterApp;
23908             synchronized (mLock) {
23909                 filterApp = (!allowedByPermission
23910                         || shouldFilterApplicationLocked(pkgSetting, callingUid, userId));
23911             }
23912             if (filterApp) {
23913                 throw new SecurityException(
23914                         "Attempt to change component state; "
23915                                 + "pid=" + Binder.getCallingPid()
23916                                 + ", uid=" + callingUid
23917                                 + (className == null
23918                                 ? ", package=" + packageName
23919                                         : ", component=" + packageName + "/" + className));
23920             }
23921             // Don't allow changing protected packages.
23922             if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
23923                 throw new SecurityException("Cannot disable a protected package: " + packageName);
23924             }
23925         }
23926         // Only allow apps with CHANGE_COMPONENT_ENABLED_STATE permission to change hidden
23927         // app details activity
23928         if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)
23929                 && !allowedByPermission) {
23930             throw new SecurityException("Cannot disable a system-generated component");
23931         }
23932 
23933         synchronized (mLock) {
23934             if (callingUid == Process.SHELL_UID
23935                     && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
23936                 // Shell can only change whole packages between ENABLED and DISABLED_USER states
23937                 // unless it is a test package.
23938                 int oldState = pkgSetting.getEnabled(userId);
23939                 if (className == null
23940                         &&
23941                         (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
23942                                 || oldState == COMPONENT_ENABLED_STATE_DEFAULT
23943                                 || oldState == COMPONENT_ENABLED_STATE_ENABLED)
23944                         &&
23945                         (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
23946                                 || newState == COMPONENT_ENABLED_STATE_DEFAULT
23947                                 || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
23948                     // ok
23949                 } else {
23950                     throw new SecurityException(
23951                             "Shell cannot change component state for " + packageName + "/"
23952                                     + className + " to " + newState);
23953                 }
23954             }
23955         }
23956         if (className == null) {
23957             // We're dealing with an application/package level state change
23958             synchronized (mLock) {
23959                 if (pkgSetting.getEnabled(userId) == newState) {
23960                     // Nothing to do
23961                     return;
23962                 }
23963             }
23964             // If we're enabling a system stub, there's a little more work to do.
23965             // Prior to enabling the package, we need to decompress the APK(s) to the
23966             // data partition and then replace the version on the system partition.
23967             final AndroidPackage deletedPkg = pkgSetting.pkg;
23968             final boolean isSystemStub = (deletedPkg != null)
23969                     && deletedPkg.isStub()
23970                     && deletedPkg.isSystem();
23971             if (isSystemStub
23972                     && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
23973                             || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
23974                 if (!enableCompressedPackage(deletedPkg, pkgSetting)) {
23975                     return;
23976                 }
23977             }
23978             if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
23979                 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
23980                 // Don't care about who enables an app.
23981                 callingPackage = null;
23982             }
23983             synchronized (mLock) {
23984                 pkgSetting.setEnabled(newState, userId, callingPackage);
23985                 if ((newState == COMPONENT_ENABLED_STATE_DISABLED_USER
23986                         || newState == COMPONENT_ENABLED_STATE_DISABLED)
23987                         && checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
23988                         == PERMISSION_GRANTED) {
23989                     // This app should not generally be allowed to get disabled by the UI, but if it
23990                     // ever does, we don't want to end up with some of the user's apps permanently
23991                     // suspended.
23992                     unsuspendForSuspendingPackage(packageName, userId);
23993                     removeAllDistractingPackageRestrictions(userId);
23994                 }
23995             }
23996         } else {
23997             synchronized (mLock) {
23998                 // We're dealing with a component level state change
23999                 // First, verify that this is a valid class name.
24000                 AndroidPackage pkg = pkgSetting.pkg;
24001                 if (pkg == null || !AndroidPackageUtils.hasComponentClassName(pkg, className)) {
24002                     if (pkg != null &&
24003                             pkg.getTargetSdkVersion() >=
24004                                     Build.VERSION_CODES.JELLY_BEAN) {
24005                         throw new IllegalArgumentException("Component class " + className
24006                                 + " does not exist in " + packageName);
24007                     } else {
24008                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
24009                                 + className + " does not exist in " + packageName);
24010                     }
24011                 }
24012                 switch (newState) {
24013                     case COMPONENT_ENABLED_STATE_ENABLED:
24014                         if (!pkgSetting.enableComponentLPw(className, userId)) {
24015                             return;
24016                         }
24017                         break;
24018                     case COMPONENT_ENABLED_STATE_DISABLED:
24019                         if (!pkgSetting.disableComponentLPw(className, userId)) {
24020                             return;
24021                         }
24022                         break;
24023                     case COMPONENT_ENABLED_STATE_DEFAULT:
24024                         if (!pkgSetting.restoreComponentLPw(className, userId)) {
24025                             return;
24026                         }
24027                         break;
24028                     default:
24029                         Slog.e(TAG, "Invalid new component state: " + newState);
24030                         return;
24031                 }
24032             }
24033         }
24034         synchronized (mLock) {
24035             if ((flags & PackageManager.SYNCHRONOUS) != 0) {
24036                 flushPackageRestrictionsAsUserInternalLocked(userId);
24037             } else {
24038                 scheduleWritePackageRestrictionsLocked(userId);
24039             }
24040             updateSequenceNumberLP(pkgSetting, new int[] { userId });
24041             final long callingId = Binder.clearCallingIdentity();
24042             try {
24043                 updateInstantAppInstallerLocked(packageName);
24044             } finally {
24045                 Binder.restoreCallingIdentity(callingId);
24046             }
24047             components = mPendingBroadcasts.get(userId, packageName);
24048             final boolean newPackage = components == null;
24049             if (newPackage) {
24050                 components = new ArrayList<>();
24051             }
24052             if (!components.contains(componentName)) {
24053                 components.add(componentName);
24054             }
24055             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
24056                 sendNow = true;
24057                 // Purge entry from pending broadcast list if another one exists already
24058                 // since we are sending one right away.
24059                 mPendingBroadcasts.remove(userId, packageName);
24060             } else {
24061                 if (newPackage) {
24062                     mPendingBroadcasts.put(userId, packageName, components);
24063                 }
24064                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
24065                     // Schedule a message - if it has been a "reasonably long time" since the
24066                     // service started, send the broadcast with a delay of one second to avoid
24067                     // delayed reactions from the receiver, else keep the default ten second delay
24068                     // to avoid extreme thrashing on service startup.
24069                     final long broadcastDelay = SystemClock.uptimeMillis() > mServiceStartWithDelay
24070                                                 ? BROADCAST_DELAY
24071                                                 : BROADCAST_DELAY_DURING_STARTUP;
24072                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, broadcastDelay);
24073                 }
24074             }
24075         }
24076 
24077         final long callingId = Binder.clearCallingIdentity();
24078         try {
24079             if (sendNow) {
24080                 int packageUid = UserHandle.getUid(userId, pkgSetting.appId);
24081                 sendPackageChangedBroadcast(packageName,
24082                         (flags & PackageManager.DONT_KILL_APP) != 0, components, packageUid, null);
24083             }
24084         } finally {
24085             Binder.restoreCallingIdentity(callingId);
24086         }
24087     }
24088 
24089     @WorkerThread
24090     @Override
24091     public void flushPackageRestrictionsAsUser(int userId) {
24092         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24093             return;
24094         }
24095         if (!mUserManager.exists(userId)) {
24096             return;
24097         }
24098         enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
24099                 false /* checkShell */, "flushPackageRestrictions");
24100         synchronized (mLock) {
24101             flushPackageRestrictionsAsUserInternalLocked(userId);
24102         }
24103     }
24104 
24105     @GuardedBy("mLock")
24106     private void flushPackageRestrictionsAsUserInternalLocked(int userId) {
24107         // NOTE: this invokes synchronous disk access, so callers using this
24108         // method should consider running on a background thread
24109         mSettings.writePackageRestrictionsLPr(userId);
24110         mDirtyUsers.remove(userId);
24111         if (mDirtyUsers.isEmpty()) {
24112             mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
24113         }
24114     }
24115 
24116     private void sendPackageChangedBroadcast(String packageName,
24117             boolean dontKillApp, ArrayList<String> componentNames, int packageUid, String reason) {
24118         if (DEBUG_INSTALL)
24119             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
24120                     + componentNames);
24121         Bundle extras = new Bundle(4);
24122         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
24123         String nameList[] = new String[componentNames.size()];
24124         componentNames.toArray(nameList);
24125         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
24126         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, dontKillApp);
24127         extras.putInt(Intent.EXTRA_UID, packageUid);
24128         if (reason != null) {
24129             extras.putString(Intent.EXTRA_REASON, reason);
24130         }
24131         // If this is not reporting a change of the overall package, then only send it
24132         // to registered receivers.  We don't want to launch a swath of apps for every
24133         // little component state change.
24134         final int flags = !componentNames.contains(packageName)
24135                 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
24136         final int userId = UserHandle.getUserId(packageUid);
24137         final boolean isInstantApp = isInstantApp(packageName, userId);
24138         final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
24139         final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
24140         final SparseArray<int[]> broadcastAllowList;
24141         synchronized (mLock) {
24142             PackageSetting setting = getPackageSettingInternal(packageName, Process.SYSTEM_UID);
24143             if (setting == null) {
24144                 return;
24145             }
24146             broadcastAllowList = isInstantApp ? null : mAppsFilter.getVisibilityAllowList(setting,
24147                     userIds, mSettings.getPackagesLocked());
24148         }
24149         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
24150                 userIds, instantUserIds, broadcastAllowList, null);
24151     }
24152 
24153     @Override
24154     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
24155         if (!mUserManager.exists(userId)) return;
24156         final int callingUid = Binder.getCallingUid();
24157         if (getInstantAppPackageName(callingUid) != null) {
24158             return;
24159         }
24160         final int permission = mContext.checkCallingOrSelfPermission(
24161                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
24162         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
24163         if (!allowedByPermission
24164                 && !ArrayUtils.contains(getPackagesForUid(callingUid), packageName)) {
24165             throw new SecurityException(
24166                     "Permission Denial: attempt to change stopped state from pid="
24167                             + Binder.getCallingPid()
24168                             + ", uid=" + callingUid + ", package=" + packageName);
24169         }
24170         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
24171                 true /* checkShell */, "stop package");
24172         boolean shouldUnhibernate = false;
24173         // writer
24174         synchronized (mLock) {
24175             final PackageSetting ps = mSettings.getPackageLPr(packageName);
24176             if (ps != null && ps.getStopped(userId) && !stopped) {
24177                 shouldUnhibernate = true;
24178             }
24179             if (!shouldFilterApplicationLocked(ps, callingUid, userId)
24180                     && mSettings.setPackageStoppedStateLPw(this, packageName, stopped, userId)) {
24181                 scheduleWritePackageRestrictionsLocked(userId);
24182             }
24183         }
24184         if (shouldUnhibernate) {
24185             mHandler.post(() -> {
24186                 AppHibernationManagerInternal ah =
24187                         mInjector.getLocalService(AppHibernationManagerInternal.class);
24188                 ah.setHibernatingForUser(packageName, userId, false);
24189                 ah.setHibernatingGlobally(packageName, false);
24190             });
24191         }
24192     }
24193 
24194     @Override
24195     public String getInstallerPackageName(String packageName) {
24196         final int callingUid = Binder.getCallingUid();
24197         synchronized (mLock) {
24198             final InstallSource installSource = getInstallSourceLocked(packageName, callingUid);
24199             if (installSource == null) {
24200                 throw new IllegalArgumentException("Unknown package: " + packageName);
24201             }
24202             String installerPackageName = installSource.installerPackageName;
24203             if (installerPackageName != null) {
24204                 final PackageSetting ps = mSettings.getPackageLPr(installerPackageName);
24205                 if (ps == null || shouldFilterApplicationLocked(ps, callingUid,
24206                         UserHandle.getUserId(callingUid))) {
24207                     installerPackageName = null;
24208                 }
24209             }
24210             return installerPackageName;
24211         }
24212     }
24213 
24214     @Override
24215     @Nullable
24216     public InstallSourceInfo getInstallSourceInfo(String packageName) {
24217         final int callingUid = Binder.getCallingUid();
24218         final int userId = UserHandle.getUserId(callingUid);
24219 
24220         String installerPackageName;
24221         String initiatingPackageName;
24222         String originatingPackageName;
24223 
24224         final InstallSource installSource;
24225         synchronized (mLock) {
24226             installSource = getInstallSourceLocked(packageName, callingUid);
24227             if (installSource == null) {
24228                 return null;
24229             }
24230 
24231             installerPackageName = installSource.installerPackageName;
24232             if (installerPackageName != null) {
24233                 final PackageSetting ps = mSettings.getPackageLPr(installerPackageName);
24234                 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
24235                     installerPackageName = null;
24236                 }
24237             }
24238 
24239             if (installSource.isInitiatingPackageUninstalled) {
24240                 // We can't check visibility in the usual way, since the initiating package is no
24241                 // longer present. So we apply simpler rules to whether to expose the info:
24242                 // 1. Instant apps can't see it.
24243                 // 2. Otherwise only the installed app itself can see it.
24244                 final boolean isInstantApp = getInstantAppPackageName(callingUid) != null;
24245                 if (!isInstantApp && isCallerSameApp(packageName, callingUid)) {
24246                     initiatingPackageName = installSource.initiatingPackageName;
24247                 } else {
24248                     initiatingPackageName = null;
24249                 }
24250             } else {
24251                 // All installSource strings are interned, so == is ok here
24252                 if (installSource.initiatingPackageName == installSource.installerPackageName) {
24253                     // The installer and initiator will often be the same, and when they are
24254                     // we can skip doing the same check again.
24255                     initiatingPackageName = installerPackageName;
24256                 } else {
24257                     initiatingPackageName = installSource.initiatingPackageName;
24258                     final PackageSetting ps = mSettings.getPackageLPr(initiatingPackageName);
24259                     if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
24260                         initiatingPackageName = null;
24261                     }
24262                 }
24263             }
24264 
24265             originatingPackageName = installSource.originatingPackageName;
24266             if (originatingPackageName != null) {
24267                 final PackageSetting ps = mSettings.getPackageLPr(originatingPackageName);
24268                 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
24269                     originatingPackageName = null;
24270                 }
24271             }
24272         }
24273 
24274         // Remaining work can safely be done outside the lock. (Note that installSource is
24275         // immutable so it's ok to carry on reading from it.)
24276 
24277         if (originatingPackageName != null && mContext.checkCallingOrSelfPermission(
24278                 Manifest.permission.INSTALL_PACKAGES) != PackageManager.PERMISSION_GRANTED) {
24279             originatingPackageName = null;
24280         }
24281 
24282         // If you can see the initiatingPackageName, and we have valid signing info for it,
24283         // then we let you see that too.
24284         final SigningInfo initiatingPackageSigningInfo;
24285         final PackageSignatures signatures = installSource.initiatingPackageSignatures;
24286         if (initiatingPackageName != null && signatures != null
24287                 && signatures.mSigningDetails != SigningDetails.UNKNOWN) {
24288             initiatingPackageSigningInfo = new SigningInfo(signatures.mSigningDetails);
24289         } else {
24290             initiatingPackageSigningInfo = null;
24291         }
24292 
24293         return new InstallSourceInfo(initiatingPackageName, initiatingPackageSigningInfo,
24294                 originatingPackageName, installerPackageName);
24295     }
24296 
24297     @GuardedBy("mLock")
24298     @Nullable
24299     private InstallSource getInstallSourceLocked(String packageName, int callingUid) {
24300         final PackageSetting ps = mSettings.getPackageLPr(packageName);
24301 
24302         // Installer info for Apex is not stored in PackageManager
24303         if (ps == null && mApexManager.isApexPackage(packageName)) {
24304             return InstallSource.EMPTY;
24305         }
24306 
24307         if (ps == null || shouldFilterApplicationLocked(ps, callingUid,
24308                 UserHandle.getUserId(callingUid))) {
24309             return null;
24310         }
24311 
24312         return ps.installSource;
24313     }
24314 
24315     public boolean isOrphaned(String packageName) {
24316         // reader
24317         synchronized (mLock) {
24318             if (!mPackages.containsKey(packageName)) {
24319                 return false;
24320             }
24321             return mSettings.isOrphaned(packageName);
24322         }
24323     }
24324 
24325     @Override
24326     public int getApplicationEnabledSetting(String packageName, int userId) {
24327         if (!mUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
24328         int callingUid = Binder.getCallingUid();
24329         enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
24330                 false /* checkShell */, "get enabled");
24331         // reader
24332         synchronized (mLock) {
24333             try {
24334                 if (shouldFilterApplicationLocked(
24335                         mSettings.getPackageLPr(packageName), callingUid, userId)) {
24336                     throw new PackageManager.NameNotFoundException(packageName);
24337                 }
24338                 return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
24339             } catch (PackageManager.NameNotFoundException e) {
24340                 throw new IllegalArgumentException("Unknown package: " + packageName);
24341             }
24342         }
24343     }
24344 
24345     @Override
24346     public int getComponentEnabledSetting(@NonNull ComponentName component, int userId) {
24347         int callingUid = Binder.getCallingUid();
24348         enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
24349                 false /*checkShell*/, "getComponentEnabled");
24350         return getComponentEnabledSettingInternal(component, callingUid, userId);
24351     }
24352 
24353     private int getComponentEnabledSettingInternal(ComponentName component, int callingUid,
24354             int userId) {
24355         if (component == null) return COMPONENT_ENABLED_STATE_DEFAULT;
24356         if (!mUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
24357 
24358         synchronized (mLock) {
24359             try {
24360                 if (shouldFilterApplicationLocked(
24361                         mSettings.getPackageLPr(component.getPackageName()), callingUid,
24362                         component, TYPE_UNKNOWN, userId)) {
24363                     throw new PackageManager.NameNotFoundException(component.getPackageName());
24364                 }
24365                 return mSettings.getComponentEnabledSettingLPr(component, userId);
24366             } catch (PackageManager.NameNotFoundException e) {
24367                 throw new IllegalArgumentException("Unknown component: " + component);
24368             }
24369         }
24370     }
24371 
24372     /**
24373      * @return true if the runtime app user enabled state, runtime component user enabled state,
24374      * install-time app manifest enabled state, and install-time component manifest enabled state
24375      * are all effectively enabled for the given component. Or if the component cannot be found,
24376      * returns false.
24377      */
24378     private boolean isComponentEffectivelyEnabled(@NonNull ComponentInfo componentInfo,
24379             @UserIdInt int userId) {
24380         synchronized (mLock) {
24381             try {
24382                 String packageName = componentInfo.packageName;
24383                 int appEnabledSetting =
24384                         mSettings.getApplicationEnabledSettingLPr(packageName, userId);
24385                 if (appEnabledSetting == COMPONENT_ENABLED_STATE_DEFAULT) {
24386                     if (!componentInfo.applicationInfo.enabled) {
24387                         return false;
24388                     }
24389                 } else if (appEnabledSetting != COMPONENT_ENABLED_STATE_ENABLED) {
24390                     return false;
24391                 }
24392 
24393                 int componentEnabledSetting = mSettings.getComponentEnabledSettingLPr(
24394                                 componentInfo.getComponentName(), userId);
24395                 if (componentEnabledSetting == COMPONENT_ENABLED_STATE_DEFAULT) {
24396                     return componentInfo.isEnabled();
24397                 } else if (componentEnabledSetting != COMPONENT_ENABLED_STATE_ENABLED) {
24398                     return false;
24399                 }
24400 
24401                 return true;
24402             } catch (PackageManager.NameNotFoundException ignored) {
24403                 return false;
24404             }
24405         }
24406     }
24407 
24408     @Override
24409     public void enterSafeMode() {
24410         enforceSystemOrRoot("Only the system can request entering safe mode");
24411 
24412         if (!mSystemReady) {
24413             mSafeMode = true;
24414         }
24415     }
24416 
24417     @Override
24418     public void systemReady() {
24419         enforceSystemOrRoot("Only the system can claim the system is ready");
24420 
24421         final ContentResolver resolver = mContext.getContentResolver();
24422         if (mReleaseOnSystemReady != null) {
24423             for (int i = mReleaseOnSystemReady.size() - 1; i >= 0; --i) {
24424                 final File dstCodePath = mReleaseOnSystemReady.get(i);
24425                 F2fsUtils.releaseCompressedBlocks(resolver, dstCodePath);
24426             }
24427             mReleaseOnSystemReady = null;
24428         }
24429         mSystemReady = true;
24430         ContentObserver co = new ContentObserver(mHandler) {
24431             @Override
24432             public void onChange(boolean selfChange) {
24433                 final boolean ephemeralFeatureDisabled =
24434                         Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0;
24435                 for (int userId : UserManagerService.getInstance().getUserIds()) {
24436                     final boolean instantAppsDisabledForUser =
24437                             ephemeralFeatureDisabled || Secure.getIntForUser(resolver,
24438                                     Secure.INSTANT_APPS_ENABLED, 1, userId) == 0;
24439                     mWebInstantAppsDisabled.put(userId, instantAppsDisabledForUser);
24440                 }
24441             }
24442         };
24443         mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
24444                         .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
24445                 false, co, UserHandle.USER_ALL);
24446         mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure
24447                         .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL);
24448         co.onChange(true);
24449 
24450         mAppsFilter.onSystemReady();
24451 
24452         // Disable any carrier apps. We do this very early in boot to prevent the apps from being
24453         // disabled after already being started.
24454         CarrierAppUtils.disableCarrierAppsUntilPrivileged(
24455                 mContext.getOpPackageName(), UserHandle.USER_SYSTEM, mContext);
24456 
24457         disableSkuSpecificApps();
24458 
24459         // Read the compatibilty setting when the system is ready.
24460         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
24461                 mContext.getContentResolver(),
24462                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
24463         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
24464 
24465         if (DEBUG_SETTINGS) {
24466             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
24467         }
24468 
24469         synchronized (mLock) {
24470             ArrayList<Integer> changed = mSettings.systemReady(mComponentResolver);
24471             for (int i = 0; i < changed.size(); i++) {
24472                 mSettings.writePackageRestrictionsLPr(changed.get(i));
24473             }
24474         }
24475 
24476         mUserManager.systemReady();
24477 
24478         // Watch for external volumes that come and go over time
24479         final StorageManager storage = mInjector.getSystemService(StorageManager.class);
24480         storage.registerListener(mStorageListener);
24481 
24482         mInstallerService.systemReady();
24483         mPackageDexOptimizer.systemReady();
24484 
24485         // Now that we're mostly running, clean up stale users and apps
24486         mUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
24487         reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
24488 
24489         mPermissionManager.onSystemReady();
24490 
24491         int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
24492         final List<UserInfo> livingUsers = mInjector.getUserManagerInternal().getUsers(
24493                 /* excludePartial= */ true,
24494                 /* excludeDying= */ true,
24495                 /* excludePreCreated= */ false);
24496         final int livingUserCount = livingUsers.size();
24497         for (int i = 0; i < livingUserCount; i++) {
24498             final int userId = livingUsers.get(i).id;
24499             if (mPmInternal.isPermissionUpgradeNeeded(userId)) {
24500                 grantPermissionsUserIds = ArrayUtils.appendInt(
24501                         grantPermissionsUserIds, userId);
24502             }
24503         }
24504         // If we upgraded grant all default permissions before kicking off.
24505         for (int userId : grantPermissionsUserIds) {
24506             mLegacyPermissionManager.grantDefaultPermissions(userId);
24507         }
24508         if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
24509             // If we did not grant default permissions, we preload from this the
24510             // default permission exceptions lazily to ensure we don't hit the
24511             // disk on a new user creation.
24512             mLegacyPermissionManager.scheduleReadDefaultPermissionExceptions();
24513         }
24514 
24515         if (mInstantAppResolverConnection != null) {
24516             mContext.registerReceiver(new BroadcastReceiver() {
24517                 @Override
24518                 public void onReceive(Context context, Intent intent) {
24519                     mInstantAppResolverConnection.optimisticBind();
24520                     mContext.unregisterReceiver(this);
24521                 }
24522             }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
24523         }
24524 
24525         IntentFilter overlayFilter = new IntentFilter(Intent.ACTION_OVERLAY_CHANGED);
24526         overlayFilter.addDataScheme("package");
24527         mContext.registerReceiver(new BroadcastReceiver() {
24528             @Override
24529             public void onReceive(Context context, Intent intent) {
24530                 if (intent == null) {
24531                     return;
24532                 }
24533                 Uri data = intent.getData();
24534                 if (data == null) {
24535                     return;
24536                 }
24537                 String packageName = data.getSchemeSpecificPart();
24538                 if (packageName == null) {
24539                     return;
24540                 }
24541                 AndroidPackage pkg = mPackages.get(packageName);
24542                 if (pkg == null) {
24543                     return;
24544                 }
24545                 sendPackageChangedBroadcast(pkg.getPackageName(),
24546                         true /* dontKillApp */,
24547                         new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
24548                         pkg.getUid(),
24549                         Intent.ACTION_OVERLAY_CHANGED);
24550             }
24551         }, overlayFilter);
24552 
24553         mModuleInfoProvider.systemReady();
24554 
24555         // Installer service might attempt to install some packages that have been staged for
24556         // installation on reboot. Make sure this is the last component to be call since the
24557         // installation might require other components to be ready.
24558         mInstallerService.restoreAndApplyStagedSessionIfNeeded();
24559 
24560         mExistingPackages = null;
24561 
24562         // Clear cache on flags changes.
24563         DeviceConfig.addOnPropertiesChangedListener(
24564                 NAMESPACE_PACKAGE_MANAGER_SERVICE, mInjector.getBackgroundExecutor(),
24565                 properties -> {
24566                     final Set<String> keyset = properties.getKeyset();
24567                     if (keyset.contains(PROPERTY_INCFS_DEFAULT_TIMEOUTS) || keyset.contains(
24568                             PROPERTY_KNOWN_DIGESTERS_LIST)) {
24569                         mPerUidReadTimeoutsCache = null;
24570                     }
24571                 });
24572     }
24573 
24574     public void waitForAppDataPrepared() {
24575         if (mPrepareAppDataFuture == null) {
24576             return;
24577         }
24578         ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
24579         mPrepareAppDataFuture = null;
24580     }
24581 
24582     @Override
24583     public boolean isSafeMode() {
24584         // allow instant applications
24585         return mSafeMode;
24586     }
24587 
24588     @Override
24589     public boolean hasSystemUidErrors() {
24590         // allow instant applications
24591         return mHasSystemUidErrors;
24592     }
24593 
24594     static String arrayToString(int[] array) {
24595         StringBuilder stringBuilder = new StringBuilder(128);
24596         stringBuilder.append('[');
24597         if (array != null) {
24598             for (int i=0; i<array.length; i++) {
24599                 if (i > 0) stringBuilder.append(", ");
24600                 stringBuilder.append(array[i]);
24601             }
24602         }
24603         stringBuilder.append(']');
24604         return stringBuilder.toString();
24605     }
24606 
24607     @Override
24608     public void onShellCommand(FileDescriptor in, FileDescriptor out,
24609             FileDescriptor err, String[] args, ShellCallback callback,
24610             ResultReceiver resultReceiver) {
24611         (new PackageManagerShellCommand(this, mContext,mDomainVerificationManager.getShell()))
24612                 .exec(this, in, out, err, args, callback, resultReceiver);
24613     }
24614 
24615     @SuppressWarnings("resource")
24616     @Override
24617     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
24618         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
24619 
24620         DumpState dumpState = new DumpState();
24621         ArraySet<String> permissionNames = null;
24622 
24623         int opti = 0;
24624         while (opti < args.length) {
24625             String opt = args[opti];
24626             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
24627                 break;
24628             }
24629             opti++;
24630 
24631             if ("-a".equals(opt)) {
24632                 // Right now we only know how to print all.
24633             } else if ("-h".equals(opt)) {
24634                 pw.println("Package manager dump options:");
24635                 pw.println("  [-h] [-f] [--checkin] [--all-components] [cmd] ...");
24636                 pw.println("    --checkin: dump for a checkin");
24637                 pw.println("    -f: print details of intent filters");
24638                 pw.println("    -h: print this help");
24639                 pw.println("    --all-components: include all component names in package dump");
24640                 pw.println("  cmd may be one of:");
24641                 pw.println("    apex: list active APEXes and APEX session state");
24642                 pw.println("    l[ibraries]: list known shared libraries");
24643                 pw.println("    f[eatures]: list device features");
24644                 pw.println("    k[eysets]: print known keysets");
24645                 pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
24646                 pw.println("    perm[issions]: dump permissions");
24647                 pw.println("    permission [name ...]: dump declaration and use of given permission");
24648                 pw.println("    pref[erred]: print preferred package settings");
24649                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
24650                 pw.println("    prov[iders]: dump content providers");
24651                 pw.println("    p[ackages]: dump installed packages");
24652                 pw.println("    q[ueries]: dump app queryability calculations");
24653                 pw.println("    s[hared-users]: dump shared user IDs");
24654                 pw.println("    m[essages]: print collected runtime messages");
24655                 pw.println("    v[erifiers]: print package verifier info");
24656                 pw.println("    d[omain-preferred-apps]: print domains preferred apps");
24657                 pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
24658                 pw.println("    t[imeouts]: print read timeouts for known digesters");
24659                 pw.println("    version: print database version info");
24660                 pw.println("    write: write current settings now");
24661                 pw.println("    installs: details about install sessions");
24662                 pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
24663                 pw.println("    dexopt: dump dexopt state");
24664                 pw.println("    compiler-stats: dump compiler statistics");
24665                 pw.println("    service-permissions: dump permissions required by services");
24666                 pw.println("    snapshot: dump snapshot statistics");
24667                 pw.println("    known-packages: dump known packages");
24668                 pw.println("    <package.name>: info about given package");
24669                 return;
24670             } else if ("--checkin".equals(opt)) {
24671                 dumpState.setCheckIn(true);
24672             } else if ("--all-components".equals(opt)) {
24673                 dumpState.setOptionEnabled(DumpState.OPTION_DUMP_ALL_COMPONENTS);
24674             } else if ("-f".equals(opt)) {
24675                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
24676             } else if ("--proto".equals(opt)) {
24677                 dumpProto(fd);
24678                 return;
24679             } else {
24680                 pw.println("Unknown argument: " + opt + "; use -h for help");
24681             }
24682         }
24683 
24684         // Is the caller requesting to dump a particular piece of data?
24685         if (opti < args.length) {
24686             String cmd = args[opti];
24687             opti++;
24688             // Is this a package name?
24689             if ("android".equals(cmd) || cmd.contains(".")) {
24690                 dumpState.setTargetPackageName(cmd);
24691                 // When dumping a single package, we always dump all of its
24692                 // filter information since the amount of data will be reasonable.
24693                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
24694             } else if ("check-permission".equals(cmd)) {
24695                 if (opti >= args.length) {
24696                     pw.println("Error: check-permission missing permission argument");
24697                     return;
24698                 }
24699                 String perm = args[opti];
24700                 opti++;
24701                 if (opti >= args.length) {
24702                     pw.println("Error: check-permission missing package argument");
24703                     return;
24704                 }
24705 
24706                 String pkg = args[opti];
24707                 opti++;
24708                 int user = UserHandle.getUserId(Binder.getCallingUid());
24709                 if (opti < args.length) {
24710                     try {
24711                         user = Integer.parseInt(args[opti]);
24712                     } catch (NumberFormatException e) {
24713                         pw.println("Error: check-permission user argument is not a number: "
24714                                 + args[opti]);
24715                         return;
24716                     }
24717                 }
24718 
24719                 // Normalize package name to handle renamed packages and static libs
24720                 pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
24721 
24722                 pw.println(checkPermission(perm, pkg, user));
24723                 return;
24724             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
24725                 dumpState.setDump(DumpState.DUMP_LIBS);
24726             } else if ("f".equals(cmd) || "features".equals(cmd)) {
24727                 dumpState.setDump(DumpState.DUMP_FEATURES);
24728             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
24729                 if (opti >= args.length) {
24730                     dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
24731                             | DumpState.DUMP_SERVICE_RESOLVERS
24732                             | DumpState.DUMP_RECEIVER_RESOLVERS
24733                             | DumpState.DUMP_CONTENT_RESOLVERS);
24734                 } else {
24735                     while (opti < args.length) {
24736                         String name = args[opti];
24737                         if ("a".equals(name) || "activity".equals(name)) {
24738                             dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
24739                         } else if ("s".equals(name) || "service".equals(name)) {
24740                             dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
24741                         } else if ("r".equals(name) || "receiver".equals(name)) {
24742                             dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
24743                         } else if ("c".equals(name) || "content".equals(name)) {
24744                             dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
24745                         } else {
24746                             pw.println("Error: unknown resolver table type: " + name);
24747                             return;
24748                         }
24749                         opti++;
24750                     }
24751                 }
24752             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
24753                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
24754             } else if ("permission".equals(cmd)) {
24755                 if (opti >= args.length) {
24756                     pw.println("Error: permission requires permission name");
24757                     return;
24758                 }
24759                 permissionNames = new ArraySet<>();
24760                 while (opti < args.length) {
24761                     permissionNames.add(args[opti]);
24762                     opti++;
24763                 }
24764                 dumpState.setDump(DumpState.DUMP_PERMISSIONS
24765                         | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
24766             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
24767                 dumpState.setDump(DumpState.DUMP_PREFERRED);
24768             } else if ("preferred-xml".equals(cmd)) {
24769                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
24770                 if (opti < args.length && "--full".equals(args[opti])) {
24771                     dumpState.setFullPreferred(true);
24772                     opti++;
24773                 }
24774             } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
24775                 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
24776             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
24777                 dumpState.setDump(DumpState.DUMP_PACKAGES);
24778             } else if ("q".equals(cmd) || "queries".equals(cmd)) {
24779                 dumpState.setDump(DumpState.DUMP_QUERIES);
24780             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
24781                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
24782                 if (opti < args.length && "noperm".equals(args[opti])) {
24783                     dumpState.setOptionEnabled(DumpState.OPTION_SKIP_PERMISSIONS);
24784                 }
24785             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
24786                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
24787             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
24788                 dumpState.setDump(DumpState.DUMP_MESSAGES);
24789             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
24790                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
24791             } else if ("dv".equals(cmd) || "domain-verifier".equals(cmd)) {
24792                 dumpState.setDump(DumpState.DUMP_DOMAIN_VERIFIER);
24793             } else if ("version".equals(cmd)) {
24794                 dumpState.setDump(DumpState.DUMP_VERSION);
24795             } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
24796                 dumpState.setDump(DumpState.DUMP_KEYSETS);
24797             } else if ("installs".equals(cmd)) {
24798                 dumpState.setDump(DumpState.DUMP_INSTALLS);
24799             } else if ("frozen".equals(cmd)) {
24800                 dumpState.setDump(DumpState.DUMP_FROZEN);
24801             } else if ("volumes".equals(cmd)) {
24802                 dumpState.setDump(DumpState.DUMP_VOLUMES);
24803             } else if ("dexopt".equals(cmd)) {
24804                 dumpState.setDump(DumpState.DUMP_DEXOPT);
24805             } else if ("compiler-stats".equals(cmd)) {
24806                 dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
24807             } else if ("changes".equals(cmd)) {
24808                 dumpState.setDump(DumpState.DUMP_CHANGES);
24809             } else if ("service-permissions".equals(cmd)) {
24810                 dumpState.setDump(DumpState.DUMP_SERVICE_PERMISSIONS);
24811             } else if ("known-packages".equals(cmd)) {
24812                 dumpState.setDump(DumpState.DUMP_KNOWN_PACKAGES);
24813             } else if ("t".equals(cmd) || "timeouts".equals(cmd)) {
24814                 dumpState.setDump(DumpState.DUMP_PER_UID_READ_TIMEOUTS);
24815             } else if ("snapshot".equals(cmd)) {
24816                 dumpState.setDump(DumpState.DUMP_SNAPSHOT_STATISTICS);
24817                 if (opti < args.length) {
24818                     if ("--full".equals(args[opti])) {
24819                         dumpState.setBrief(false);
24820                         opti++;
24821                     } else if ("--brief".equals(args[opti])) {
24822                         dumpState.setBrief(true);
24823                         opti++;
24824                     }
24825                 }
24826             } else if ("write".equals(cmd)) {
24827                 synchronized (mLock) {
24828                     writeSettingsLPrTEMP();
24829                     pw.println("Settings written.");
24830                     return;
24831                 }
24832             }
24833         }
24834 
24835         final String packageName = dumpState.getTargetPackageName();
24836         final boolean checkin = dumpState.isCheckIn();
24837         if (checkin) {
24838             pw.println("vers,1");
24839         }
24840 
24841         // reader
24842         if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
24843             if (!checkin) {
24844                 dump(DumpState.DUMP_VERSION, fd, pw, dumpState);
24845             }
24846         }
24847 
24848         if (!checkin
24849                 && dumpState.isDumping(DumpState.DUMP_KNOWN_PACKAGES)
24850                 && packageName == null) {
24851             if (dumpState.onTitlePrinted()) {
24852                 pw.println();
24853             }
24854             final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
24855             ipw.println("Known Packages:");
24856             ipw.increaseIndent();
24857             for (int i = 0; i <= LAST_KNOWN_PACKAGE; i++) {
24858                 final String knownPackage = mPmInternal.knownPackageToString(i);
24859                 ipw.print(knownPackage);
24860                 ipw.println(":");
24861                 final String[] pkgNames = mPmInternal.getKnownPackageNames(i,
24862                         UserHandle.USER_SYSTEM);
24863                 ipw.increaseIndent();
24864                 if (ArrayUtils.isEmpty(pkgNames)) {
24865                     ipw.println("none");
24866                 } else {
24867                     for (String name : pkgNames) {
24868                         ipw.println(name);
24869                     }
24870                 }
24871                 ipw.decreaseIndent();
24872             }
24873             ipw.decreaseIndent();
24874         }
24875 
24876         if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
24877             final String requiredVerifierPackage = mRequiredVerifierPackage;
24878             if (!checkin) {
24879                 if (dumpState.onTitlePrinted()) {
24880                     pw.println();
24881                 }
24882                 pw.println("Verifiers:");
24883                 pw.print("  Required: ");
24884                 pw.print(requiredVerifierPackage);
24885                 pw.print(" (uid=");
24886                 pw.print(getPackageUid(requiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
24887                         UserHandle.USER_SYSTEM));
24888                 pw.println(")");
24889             } else if (requiredVerifierPackage != null) {
24890                 pw.print("vrfy,"); pw.print(requiredVerifierPackage);
24891                 pw.print(",");
24892                 pw.println(getPackageUid(requiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
24893                         UserHandle.USER_SYSTEM));
24894             }
24895         }
24896 
24897         if (dumpState.isDumping(DumpState.DUMP_DOMAIN_VERIFIER) && packageName == null) {
24898             final DomainVerificationProxy proxy = mDomainVerificationManager.getProxy();
24899             final ComponentName verifierComponent = proxy.getComponentName();
24900             if (verifierComponent != null) {
24901                 String verifierPackageName = verifierComponent.getPackageName();
24902                 if (!checkin) {
24903                     if (dumpState.onTitlePrinted())
24904                         pw.println();
24905                     pw.println("Domain Verifier:");
24906                     pw.print("  Using: ");
24907                     pw.print(verifierPackageName);
24908                     pw.print(" (uid=");
24909                     pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
24910                             UserHandle.USER_SYSTEM));
24911                     pw.println(")");
24912                 } else if (verifierPackageName != null) {
24913                     pw.print("dv,"); pw.print(verifierPackageName);
24914                     pw.print(",");
24915                     pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
24916                             UserHandle.USER_SYSTEM));
24917                 }
24918             } else {
24919                 pw.println();
24920                 pw.println("No Domain Verifier available!");
24921             }
24922         }
24923 
24924         if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
24925             dump(DumpState.DUMP_LIBS, fd, pw, dumpState);
24926         }
24927 
24928         if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
24929             if (dumpState.onTitlePrinted()) {
24930                 pw.println();
24931             }
24932             if (!checkin) {
24933                 pw.println("Features:");
24934             }
24935 
24936             synchronized (mAvailableFeatures) {
24937                 for (FeatureInfo feat : mAvailableFeatures.values()) {
24938                     if (checkin) {
24939                         pw.print("feat,");
24940                         pw.print(feat.name);
24941                         pw.print(",");
24942                         pw.println(feat.version);
24943                     } else {
24944                         pw.print("  ");
24945                         pw.print(feat.name);
24946                         if (feat.version > 0) {
24947                             pw.print(" version=");
24948                             pw.print(feat.version);
24949                         }
24950                         pw.println();
24951                     }
24952                 }
24953             }
24954         }
24955 
24956         if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
24957             synchronized (mLock) {
24958                 mComponentResolver.dumpActivityResolvers(pw, dumpState, packageName);
24959             }
24960         }
24961         if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
24962             synchronized (mLock) {
24963                 mComponentResolver.dumpReceiverResolvers(pw, dumpState, packageName);
24964             }
24965         }
24966         if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
24967             synchronized (mLock) {
24968                 mComponentResolver.dumpServiceResolvers(pw, dumpState, packageName);
24969             }
24970         }
24971         if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
24972             synchronized (mLock) {
24973                 mComponentResolver.dumpProviderResolvers(pw, dumpState, packageName);
24974             }
24975         }
24976 
24977         if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
24978             dump(DumpState.DUMP_PREFERRED, fd, pw, dumpState);
24979         }
24980 
24981         if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
24982             dump(DumpState.DUMP_PREFERRED_XML, fd, pw, dumpState);
24983         }
24984 
24985         if (!checkin && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)) {
24986             dump(DumpState.DUMP_DOMAIN_PREFERRED, fd, pw, dumpState);
24987         }
24988 
24989         if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
24990             mSettings.dumpPermissions(pw, packageName, permissionNames, dumpState);
24991         }
24992 
24993         if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
24994             synchronized (mLock) {
24995                 mComponentResolver.dumpContentProviders(pw, dumpState, packageName);
24996             }
24997         }
24998 
24999         if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
25000             synchronized (mLock) {
25001                 mSettings.getKeySetManagerService().dumpLPr(pw, packageName, dumpState);
25002             }
25003         }
25004 
25005         if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
25006             // This cannot be moved to ComputerEngine since some variables of the collections
25007             // in PackageUserState such as suspendParams, disabledComponents and enabledComponents
25008             // do not have a copy.
25009             synchronized (mLock) {
25010                 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
25011             }
25012         }
25013 
25014         if (dumpState.isDumping(DumpState.DUMP_QUERIES)) {
25015             dump(DumpState.DUMP_QUERIES, fd, pw, dumpState);
25016         }
25017 
25018         if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
25019             // This cannot be moved to ComputerEngine since the set of packages in the
25020             // SharedUserSetting do not have a copy.
25021             synchronized (mLock) {
25022                 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
25023             }
25024         }
25025 
25026         if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
25027             if (dumpState.onTitlePrinted()) pw.println();
25028             pw.println("Package Changes:");
25029             synchronized (mLock) {
25030                 pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
25031                 final int K = mChangedPackages.size();
25032                 for (int i = 0; i < K; i++) {
25033                     final SparseArray<String> changes = mChangedPackages.valueAt(i);
25034                     pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
25035                     final int N = changes.size();
25036                     if (N == 0) {
25037                         pw.print("    "); pw.println("No packages changed");
25038                     } else {
25039                         for (int j = 0; j < N; j++) {
25040                             final String pkgName = changes.valueAt(j);
25041                             final int sequenceNumber = changes.keyAt(j);
25042                             pw.print("    ");
25043                             pw.print("seq=");
25044                             pw.print(sequenceNumber);
25045                             pw.print(", package=");
25046                             pw.println(pkgName);
25047                         }
25048                     }
25049                 }
25050             }
25051         }
25052 
25053         if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
25054             // XXX should handle packageName != null by dumping only install data that
25055             // the given package is involved with.
25056             if (dumpState.onTitlePrinted()) pw.println();
25057 
25058             final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
25059             ipw.println();
25060             ipw.println("Frozen packages:");
25061             ipw.increaseIndent();
25062             synchronized (mLock) {
25063                 if (mFrozenPackages.size() == 0) {
25064                     ipw.println("(none)");
25065                 } else {
25066                     for (int i = 0; i < mFrozenPackages.size(); i++) {
25067                         ipw.println(mFrozenPackages.valueAt(i));
25068                     }
25069                 }
25070             }
25071             ipw.decreaseIndent();
25072         }
25073 
25074         if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
25075             if (dumpState.onTitlePrinted()) pw.println();
25076 
25077             final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
25078             ipw.println();
25079             ipw.println("Loaded volumes:");
25080             ipw.increaseIndent();
25081             synchronized (mLoadedVolumes) {
25082                 if (mLoadedVolumes.size() == 0) {
25083                     ipw.println("(none)");
25084                 } else {
25085                     for (int i = 0; i < mLoadedVolumes.size(); i++) {
25086                         ipw.println(mLoadedVolumes.valueAt(i));
25087                     }
25088                 }
25089             }
25090             ipw.decreaseIndent();
25091         }
25092 
25093         if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
25094                 && packageName == null) {
25095             synchronized (mLock) {
25096                 mComponentResolver.dumpServicePermissions(pw, dumpState);
25097             }
25098         }
25099 
25100         if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
25101             if (dumpState.onTitlePrinted()) pw.println();
25102             dump(DumpState.DUMP_DEXOPT, fd, pw, dumpState);
25103         }
25104 
25105         if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
25106             if (dumpState.onTitlePrinted()) pw.println();
25107             dump(DumpState.DUMP_COMPILER_STATS, fd, pw, dumpState);
25108         }
25109 
25110         if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
25111             if (dumpState.onTitlePrinted()) pw.println();
25112             synchronized (mLock) {
25113                 mSettings.dumpReadMessagesLPr(pw, dumpState);
25114             }
25115             pw.println();
25116             pw.println("Package warning messages:");
25117             dumpCriticalInfo(pw, null);
25118         }
25119 
25120         if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
25121             dumpCriticalInfo(pw, "msg,");
25122         }
25123 
25124         // PackageInstaller should be called outside of mPackages lock
25125         if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
25126             // XXX should handle packageName != null by dumping only install data that
25127             // the given package is involved with.
25128             if (dumpState.onTitlePrinted()) pw.println();
25129             mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
25130         }
25131 
25132         if (!checkin && dumpState.isDumping(DumpState.DUMP_APEX)) {
25133             mApexManager.dump(pw, packageName);
25134         }
25135 
25136         if (!checkin && dumpState.isDumping(DumpState.DUMP_PER_UID_READ_TIMEOUTS)
25137                 && packageName == null) {
25138             pw.println();
25139             pw.println("Per UID read timeouts:");
25140             pw.println("    Default timeouts flag: " + getDefaultTimeouts());
25141             pw.println("    Known digesters list flag: " + getKnownDigestersList());
25142 
25143             PerUidReadTimeouts[] items = getPerUidReadTimeouts();
25144             pw.println("    Timeouts (" + items.length + "):");
25145             for (PerUidReadTimeouts item : items) {
25146                 pw.print("        (");
25147                 pw.print("uid=" + item.uid + ", ");
25148                 pw.print("minTimeUs=" + item.minTimeUs + ", ");
25149                 pw.print("minPendingTimeUs=" + item.minPendingTimeUs + ", ");
25150                 pw.print("maxPendingTimeUs=" + item.maxPendingTimeUs);
25151                 pw.println(")");
25152             }
25153         }
25154 
25155         if (!checkin && dumpState.isDumping(DumpState.DUMP_SNAPSHOT_STATISTICS)) {
25156             pw.println("Snapshot statistics");
25157             if (!mSnapshotEnabled) {
25158                 pw.println("  Snapshots disabled");
25159             } else {
25160                 int hits = 0;
25161                 int level = sSnapshotCorked.get();
25162                 synchronized (mSnapshotLock) {
25163                     if (mSnapshotComputer != null) {
25164                         hits = mSnapshotComputer.getUsed();
25165                     }
25166                 }
25167                 final long now = SystemClock.currentTimeMicro();
25168                 mSnapshotStatistics.dump(pw, "  ", now, hits, level, dumpState.isBrief());
25169             }
25170         }
25171     }
25172 
25173     /**
25174      * Dump package manager states to the file according to a given dumping type of
25175      * {@link DumpState}.
25176      */
25177     private void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) {
25178         mComputer.dump(type, fd, pw, dumpState);
25179     }
25180 
25181     //TODO: b/111402650
25182     private void disableSkuSpecificApps() {
25183         String apkList[] = mContext.getResources().getStringArray(
25184                 R.array.config_disableApksUnlessMatchedSku_apk_list);
25185         String skuArray[] = mContext.getResources().getStringArray(
25186                 R.array.config_disableApkUnlessMatchedSku_skus_list);
25187         if (ArrayUtils.isEmpty(apkList)) {
25188            return;
25189         }
25190         String sku = SystemProperties.get("ro.boot.hardware.sku");
25191         if (!TextUtils.isEmpty(sku) && ArrayUtils.contains(skuArray, sku)) {
25192             return;
25193         }
25194         for (String packageName : apkList) {
25195             setSystemAppHiddenUntilInstalled(packageName, true);
25196             for (UserInfo user : mInjector.getUserManagerInternal().getUsers(false)) {
25197                 setSystemAppInstallState(packageName, false, user.id);
25198             }
25199         }
25200     }
25201 
25202     private void dumpProto(FileDescriptor fd) {
25203         final ProtoOutputStream proto = new ProtoOutputStream(fd);
25204 
25205         synchronized (mLock) {
25206             final long requiredVerifierPackageToken =
25207                     proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
25208             proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
25209             proto.write(
25210                     PackageServiceDumpProto.PackageShortProto.UID,
25211                     getPackageUid(
25212                             mRequiredVerifierPackage,
25213                             MATCH_DEBUG_TRIAGED_MISSING,
25214                             UserHandle.USER_SYSTEM));
25215             proto.end(requiredVerifierPackageToken);
25216 
25217             DomainVerificationProxy proxy = mDomainVerificationManager.getProxy();
25218             ComponentName verifierComponent = proxy.getComponentName();
25219             if (verifierComponent != null) {
25220                 String verifierPackageName = verifierComponent.getPackageName();
25221                 final long verifierPackageToken =
25222                         proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
25223                 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
25224                 proto.write(
25225                         PackageServiceDumpProto.PackageShortProto.UID,
25226                         getPackageUid(
25227                                 verifierPackageName,
25228                                 MATCH_DEBUG_TRIAGED_MISSING,
25229                                 UserHandle.USER_SYSTEM));
25230                 proto.end(verifierPackageToken);
25231             }
25232 
25233             dumpSharedLibrariesProto(proto);
25234             dumpFeaturesProto(proto);
25235             mSettings.dumpPackagesProto(proto);
25236             mSettings.dumpSharedUsersProto(proto);
25237             dumpCriticalInfo(proto);
25238         }
25239         proto.flush();
25240     }
25241 
25242     private void dumpFeaturesProto(ProtoOutputStream proto) {
25243         synchronized (mAvailableFeatures) {
25244             final int count = mAvailableFeatures.size();
25245             for (int i = 0; i < count; i++) {
25246                 mAvailableFeatures.valueAt(i).dumpDebug(proto, PackageServiceDumpProto.FEATURES);
25247             }
25248         }
25249     }
25250 
25251     private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
25252         final int count = mSharedLibraries.size();
25253         for (int i = 0; i < count; i++) {
25254             final String libName = mSharedLibraries.keyAt(i);
25255             WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(libName);
25256             if (versionedLib == null) {
25257                 continue;
25258             }
25259             final int versionCount = versionedLib.size();
25260             for (int j = 0; j < versionCount; j++) {
25261                 final SharedLibraryInfo libraryInfo = versionedLib.valueAt(j);
25262                 final long sharedLibraryToken =
25263                         proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
25264                 proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libraryInfo.getName());
25265                 final boolean isJar = (libraryInfo.getPath() != null);
25266                 proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
25267                 if (isJar) {
25268                     proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH,
25269                             libraryInfo.getPath());
25270                 } else {
25271                     proto.write(PackageServiceDumpProto.SharedLibraryProto.APK,
25272                             libraryInfo.getPackageName());
25273                 }
25274                 proto.end(sharedLibraryToken);
25275             }
25276         }
25277     }
25278 
25279     // ------- apps on sdcard specific code -------
25280     static final boolean DEBUG_SD_INSTALL = false;
25281 
25282     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
25283 
25284     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
25285 
25286     private boolean mMediaMounted = false;
25287 
25288     static String getEncryptKey() {
25289         try {
25290             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
25291                     SD_ENCRYPTION_KEYSTORE_NAME);
25292             if (sdEncKey == null) {
25293                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
25294                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
25295                 if (sdEncKey == null) {
25296                     Slog.e(TAG, "Failed to create encryption keys");
25297                     return null;
25298                 }
25299             }
25300             return sdEncKey;
25301         } catch (NoSuchAlgorithmException nsae) {
25302             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
25303             return null;
25304         } catch (IOException ioe) {
25305             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
25306             return null;
25307         }
25308     }
25309 
25310     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
25311             ArrayList<AndroidPackage> packages, IIntentReceiver finishedReceiver) {
25312         final int size = packages.size();
25313         final String[] packageNames = new String[size];
25314         final int[] packageUids = new int[size];
25315         for (int i = 0; i < size; i++) {
25316             final AndroidPackage pkg = packages.get(i);
25317             packageNames[i] = pkg.getPackageName();
25318             packageUids[i] = pkg.getUid();
25319         }
25320         sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
25321                 finishedReceiver);
25322     }
25323 
25324     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
25325             ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
25326         sendResourcesChangedBroadcast(mediaStatus, replacing,
25327                 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
25328     }
25329 
25330     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
25331             String[] pkgList, int[] uidArr, IIntentReceiver finishedReceiver) {
25332         int size = pkgList.length;
25333         if (size > 0) {
25334             // Send broadcasts here
25335             Bundle extras = new Bundle();
25336             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
25337             if (uidArr != null) {
25338                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
25339             }
25340             if (replacing) {
25341                 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
25342             }
25343             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
25344                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
25345             // TODO: not sure how to handle this one.
25346             sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver,
25347                     null, null, null, null);
25348         }
25349     }
25350 
25351     private void loadPrivatePackages(final VolumeInfo vol) {
25352         mHandler.post(() -> loadPrivatePackagesInner(vol));
25353     }
25354 
25355     private void loadPrivatePackagesInner(VolumeInfo vol) {
25356         final String volumeUuid = vol.fsUuid;
25357         if (TextUtils.isEmpty(volumeUuid)) {
25358             Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
25359             return;
25360         }
25361 
25362         final ArrayList<PackageFreezer> freezers = new ArrayList<>();
25363         final ArrayList<AndroidPackage> loaded = new ArrayList<>();
25364         final int parseFlags = mDefParseFlags | ParsingPackageUtils.PARSE_EXTERNAL_STORAGE;
25365 
25366         final VersionInfo ver;
25367         final List<PackageSetting> packages;
25368         synchronized (mLock) {
25369             ver = mSettings.findOrCreateVersion(volumeUuid);
25370             packages = mSettings.getVolumePackagesLPr(volumeUuid);
25371         }
25372 
25373         for (PackageSetting ps : packages) {
25374             freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
25375             synchronized (mInstallLock) {
25376                 final AndroidPackage pkg;
25377                 try {
25378                     pkg = scanPackageTracedLI(ps.getPath(), parseFlags, SCAN_INITIAL, 0, null);
25379                     loaded.add(pkg);
25380 
25381                 } catch (PackageManagerException e) {
25382                     Slog.w(TAG, "Failed to scan " + ps.getPath() + ": " + e.getMessage());
25383                 }
25384 
25385                 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
25386                     clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
25387                             | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY
25388                             | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
25389                 }
25390             }
25391         }
25392 
25393         // Reconcile app data for all started/unlocked users
25394         final StorageManager sm = mInjector.getSystemService(StorageManager.class);
25395         UserManagerInternal umInternal = mInjector.getUserManagerInternal();
25396         for (UserInfo user : mUserManager.getUsers(false /* includeDying */)) {
25397             final int flags;
25398             if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
25399                 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
25400             } else if (umInternal.isUserRunning(user.id)) {
25401                 flags = StorageManager.FLAG_STORAGE_DE;
25402             } else {
25403                 continue;
25404             }
25405 
25406             try {
25407                 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
25408                 synchronized (mInstallLock) {
25409                     reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
25410                 }
25411             } catch (IllegalStateException e) {
25412                 // Device was probably ejected, and we'll process that event momentarily
25413                 Slog.w(TAG, "Failed to prepare storage: " + e);
25414             }
25415         }
25416 
25417         synchronized (mLock) {
25418             final boolean isUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
25419             if (isUpgrade) {
25420                 logCriticalInfo(Log.INFO, "Build fingerprint changed from " + ver.fingerprint
25421                         + " to " + Build.FINGERPRINT + "; regranting permissions for "
25422                         + volumeUuid);
25423             }
25424             mPermissionManager.onStorageVolumeMounted(volumeUuid, isUpgrade);
25425 
25426             // Yay, everything is now upgraded
25427             ver.forceCurrent();
25428 
25429             writeSettingsLPrTEMP();
25430         }
25431 
25432         for (PackageFreezer freezer : freezers) {
25433             freezer.close();
25434         }
25435 
25436         if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
25437         sendResourcesChangedBroadcast(true, false, loaded, null);
25438         synchronized (mLoadedVolumes) {
25439             mLoadedVolumes.add(vol.getId());
25440         }
25441     }
25442 
25443     private void unloadPrivatePackages(final VolumeInfo vol) {
25444         mHandler.post(() -> unloadPrivatePackagesInner(vol));
25445     }
25446 
25447     private void unloadPrivatePackagesInner(VolumeInfo vol) {
25448         final String volumeUuid = vol.fsUuid;
25449         if (TextUtils.isEmpty(volumeUuid)) {
25450             Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
25451             return;
25452         }
25453 
25454         final int[] userIds = mUserManager.getUserIds();
25455         final ArrayList<AndroidPackage> unloaded = new ArrayList<>();
25456         synchronized (mInstallLock) {
25457             synchronized (mLock) {
25458                 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
25459                 for (PackageSetting ps : packages) {
25460                     if (ps.pkg == null) continue;
25461 
25462                     final AndroidPackage pkg = ps.pkg;
25463                     final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
25464                     final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
25465 
25466                     try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
25467                             "unloadPrivatePackagesInner")) {
25468                         if (deletePackageLIF(ps.name, null, false, userIds, deleteFlags, outInfo,
25469                                 false, null)) {
25470                             unloaded.add(pkg);
25471                         } else {
25472                             Slog.w(TAG, "Failed to unload " + ps.getPath());
25473                         }
25474                     }
25475 
25476                     // Try very hard to release any references to this package
25477                     // so we don't risk the system server being killed due to
25478                     // open FDs
25479                     AttributeCache.instance().removePackage(ps.name);
25480                 }
25481 
25482                 writeSettingsLPrTEMP();
25483             }
25484         }
25485 
25486         if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
25487         sendResourcesChangedBroadcast(false, false, unloaded, null);
25488         synchronized (mLoadedVolumes) {
25489             mLoadedVolumes.remove(vol.getId());
25490         }
25491 
25492         // Try very hard to release any references to this path so we don't risk
25493         // the system server being killed due to open FDs
25494         ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
25495 
25496         for (int i = 0; i < 3; i++) {
25497             System.gc();
25498             System.runFinalization();
25499         }
25500     }
25501 
25502     private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
25503             throws PackageManagerException {
25504         synchronized (mLock) {
25505             // Normalize package name to handle renamed packages
25506             packageName = normalizePackageNameLPr(packageName);
25507 
25508             final PackageSetting ps = mSettings.getPackageLPr(packageName);
25509             if (ps == null) {
25510                 throw new PackageManagerException("Package " + packageName + " is unknown");
25511             } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
25512                 throw new PackageManagerException(
25513                         "Package " + packageName + " found on unknown volume " + volumeUuid
25514                                 + "; expected volume " + ps.volumeUuid);
25515             } else if (!ps.getInstalled(userId)) {
25516                 throw new PackageManagerException(
25517                         "Package " + packageName + " not installed for user " + userId);
25518             }
25519         }
25520     }
25521 
25522     private List<String> collectAbsoluteCodePaths() {
25523         synchronized (mLock) {
25524             List<String> codePaths = new ArrayList<>();
25525             final int packageCount = mSettings.getPackagesLocked().size();
25526             for (int i = 0; i < packageCount; i++) {
25527                 final PackageSetting ps = mSettings.getPackagesLocked().valueAt(i);
25528                 codePaths.add(ps.getPath().getAbsolutePath());
25529             }
25530             return codePaths;
25531         }
25532     }
25533 
25534     private void executeBatchLI(@NonNull Installer.Batch batch) {
25535         try {
25536             batch.execute(mInstaller);
25537         } catch (InstallerException e) {
25538             Slog.w(TAG, "Failed to execute pending operations", e);
25539         }
25540     }
25541 
25542     /**
25543      * Examine all apps present on given mounted volume, and destroy apps that
25544      * aren't expected, either due to uninstallation or reinstallation on
25545      * another volume.
25546      */
25547     private void reconcileApps(String volumeUuid) {
25548         List<String> absoluteCodePaths = collectAbsoluteCodePaths();
25549         List<File> filesToDelete = null;
25550 
25551         final File[] files = FileUtils.listFilesOrEmpty(
25552                 Environment.getDataAppDirectory(volumeUuid));
25553         for (File file : files) {
25554             final boolean isPackage = (isApkFile(file) || file.isDirectory())
25555                     && !PackageInstallerService.isStageName(file.getName());
25556             if (!isPackage) {
25557                 // Ignore entries which are not packages
25558                 continue;
25559             }
25560 
25561             String absolutePath = file.getAbsolutePath();
25562 
25563             boolean pathValid = false;
25564             final int absoluteCodePathCount = absoluteCodePaths.size();
25565             for (int i = 0; i < absoluteCodePathCount; i++) {
25566                 String absoluteCodePath = absoluteCodePaths.get(i);
25567                 if (absoluteCodePath.startsWith(absolutePath)) {
25568                     pathValid = true;
25569                     break;
25570                 }
25571             }
25572 
25573             if (!pathValid) {
25574                 if (filesToDelete == null) {
25575                     filesToDelete = new ArrayList<>();
25576                 }
25577                 filesToDelete.add(file);
25578             }
25579         }
25580 
25581         if (filesToDelete != null) {
25582             final int fileToDeleteCount = filesToDelete.size();
25583             for (int i = 0; i < fileToDeleteCount; i++) {
25584                 File fileToDelete = filesToDelete.get(i);
25585                 logCriticalInfo(Log.WARN, "Destroying orphaned at " + fileToDelete);
25586                 synchronized (mInstallLock) {
25587                     removeCodePathLI(fileToDelete);
25588                 }
25589             }
25590         }
25591     }
25592 
25593     /**
25594      * Reconcile all app data for the given user.
25595      * <p>
25596      * Verifies that directories exist and that ownership and labeling is
25597      * correct for all installed apps on all mounted volumes.
25598      */
25599     void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
25600         final StorageManager storage = mInjector.getSystemService(StorageManager.class);
25601         for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
25602             final String volumeUuid = vol.getFsUuid();
25603             synchronized (mInstallLock) {
25604                 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
25605             }
25606         }
25607     }
25608 
25609     @GuardedBy("mInstallLock")
25610     private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
25611             boolean migrateAppData) {
25612         reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
25613     }
25614 
25615     /**
25616      * Reconcile all app data on given mounted volume.
25617      * <p>
25618      * Destroys app data that isn't expected, either due to uninstallation or
25619      * reinstallation on another volume.
25620      * <p>
25621      * Verifies that directories exist and that ownership and labeling is
25622      * correct for all installed apps.
25623      * @return list of skipped non-core packages (if {@code onlyCoreApps} is true)
25624      */
25625     @GuardedBy("mInstallLock")
25626     private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
25627             boolean migrateAppData, boolean onlyCoreApps) {
25628         Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
25629                 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
25630         List<String> result = onlyCoreApps ? new ArrayList<>() : null;
25631 
25632         final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
25633         final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
25634 
25635         // First look for stale data that doesn't belong, and check if things
25636         // have changed since we did our last restorecon
25637         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
25638             if (StorageManager.isFileEncryptedNativeOrEmulated()
25639                     && !StorageManager.isUserKeyUnlocked(userId)) {
25640                 throw new RuntimeException(
25641                         "Yikes, someone asked us to reconcile CE storage while " + userId
25642                                 + " was still locked; this would have caused massive data loss!");
25643             }
25644 
25645             final File[] files = FileUtils.listFilesOrEmpty(ceDir);
25646             for (File file : files) {
25647                 final String packageName = file.getName();
25648                 try {
25649                     assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
25650                 } catch (PackageManagerException e) {
25651                     logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
25652                     try {
25653                         mInstaller.destroyAppData(volumeUuid, packageName, userId,
25654                                 StorageManager.FLAG_STORAGE_CE, 0);
25655                     } catch (InstallerException e2) {
25656                         logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
25657                     }
25658                 }
25659             }
25660         }
25661         if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
25662             final File[] files = FileUtils.listFilesOrEmpty(deDir);
25663             for (File file : files) {
25664                 final String packageName = file.getName();
25665                 try {
25666                     assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
25667                 } catch (PackageManagerException e) {
25668                     logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
25669                     try {
25670                         mInstaller.destroyAppData(volumeUuid, packageName, userId,
25671                                 StorageManager.FLAG_STORAGE_DE, 0);
25672                     } catch (InstallerException e2) {
25673                         logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
25674                     }
25675                 }
25676             }
25677         }
25678 
25679         // Ensure that data directories are ready to roll for all packages
25680         // installed for this volume and user
25681         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "prepareAppDataAndMigrate");
25682         Installer.Batch batch = new Installer.Batch();
25683         final List<PackageSetting> packages;
25684         synchronized (mLock) {
25685             packages = mSettings.getVolumePackagesLPr(volumeUuid);
25686         }
25687         int preparedCount = 0;
25688         for (PackageSetting ps : packages) {
25689             final String packageName = ps.name;
25690             if (ps.pkg == null) {
25691                 Slog.w(TAG, "Odd, missing scanned package " + packageName);
25692                 // TODO: might be due to legacy ASEC apps; we should circle back
25693                 // and reconcile again once they're scanned
25694                 continue;
25695             }
25696             // Skip non-core apps if requested
25697             if (onlyCoreApps && !ps.pkg.isCoreApp()) {
25698                 result.add(packageName);
25699                 continue;
25700             }
25701 
25702             if (ps.getInstalled(userId)) {
25703                 prepareAppDataAndMigrate(batch, ps.pkg, userId, flags, migrateAppData);
25704                 preparedCount++;
25705             }
25706         }
25707         executeBatchLI(batch);
25708         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
25709 
25710         Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
25711         return result;
25712     }
25713 
25714     /**
25715      * Prepare app data for the given app just after it was installed or
25716      * upgraded. This method carefully only touches users that it's installed
25717      * for, and it forces a restorecon to handle any seinfo changes.
25718      * <p>
25719      * Verifies that directories exist and that ownership and labeling is
25720      * correct for all installed apps. If there is an ownership mismatch, it
25721      * will try recovering system apps by wiping data; third-party app data is
25722      * left intact.
25723      * <p>
25724      * <em>Note: To avoid a deadlock, do not call this method with {@code mLock} lock held</em>
25725      */
25726     private void prepareAppDataAfterInstallLIF(AndroidPackage pkg) {
25727         final PackageSetting ps;
25728         synchronized (mLock) {
25729             ps = mSettings.getPackageLPr(pkg.getPackageName());
25730             mSettings.writeKernelMappingLPr(ps);
25731         }
25732 
25733         Installer.Batch batch = new Installer.Batch();
25734         UserManagerInternal umInternal = mInjector.getUserManagerInternal();
25735         StorageManagerInternal smInternal = mInjector.getLocalService(StorageManagerInternal.class);
25736         for (UserInfo user : mUserManager.getUsers(false /*excludeDying*/)) {
25737             final int flags;
25738             if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
25739                 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
25740             } else if (umInternal.isUserRunning(user.id)) {
25741                 flags = StorageManager.FLAG_STORAGE_DE;
25742             } else {
25743                 continue;
25744             }
25745 
25746             if (ps.getInstalled(user.id)) {
25747                 // TODO: when user data is locked, mark that we're still dirty
25748                 prepareAppData(batch, pkg, user.id, flags).thenRun(() -> {
25749                     // Note: this code block is executed with the Installer lock
25750                     // already held, since it's invoked as a side-effect of
25751                     // executeBatchLI()
25752                     if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
25753                         // Prepare app data on external storage; currently this is used to
25754                         // setup any OBB dirs that were created by the installer correctly.
25755                         int uid = UserHandle.getUid(user.id, UserHandle.getAppId(pkg.getUid()));
25756                         smInternal.prepareAppDataAfterInstall(pkg.getPackageName(), uid);
25757                     }
25758                 });
25759             }
25760         }
25761         executeBatchLI(batch);
25762     }
25763 
25764     /**
25765      * Prepare app data for the given app.
25766      * <p>
25767      * Verifies that directories exist and that ownership and labeling is
25768      * correct for all installed apps. If there is an ownership mismatch, this
25769      * will try recovering system apps by wiping data; third-party app data is
25770      * left intact.
25771      */
25772     private @NonNull CompletableFuture<?> prepareAppData(@NonNull Installer.Batch batch,
25773             @Nullable AndroidPackage pkg, int userId, int flags) {
25774         if (pkg == null) {
25775             Slog.wtf(TAG, "Package was null!", new Throwable());
25776             return CompletableFuture.completedFuture(null);
25777         }
25778         return prepareAppDataLeaf(batch, pkg, userId, flags);
25779     }
25780 
25781     private @NonNull CompletableFuture<?> prepareAppDataAndMigrate(@NonNull Installer.Batch batch,
25782             @NonNull AndroidPackage pkg, int userId, int flags, boolean maybeMigrateAppData) {
25783         return prepareAppData(batch, pkg, userId, flags).thenRun(() -> {
25784             // Note: this code block is executed with the Installer lock
25785             // already held, since it's invoked as a side-effect of
25786             // executeBatchLI()
25787             if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
25788                 // We may have just shuffled around app data directories, so
25789                 // prepare them one more time
25790                 final Installer.Batch batchInner = new Installer.Batch();
25791                 prepareAppData(batchInner, pkg, userId, flags);
25792                 executeBatchLI(batchInner);
25793             }
25794         });
25795     }
25796 
25797     private @NonNull CompletableFuture<?> prepareAppDataLeaf(@NonNull Installer.Batch batch,
25798             @NonNull AndroidPackage pkg, int userId, int flags) {
25799         if (DEBUG_APP_DATA) {
25800             Slog.v(TAG, "prepareAppData for " + pkg.getPackageName() + " u" + userId + " 0x"
25801                     + Integer.toHexString(flags));
25802         }
25803 
25804         final PackageSetting ps;
25805         synchronized (mLock) {
25806             ps = mSettings.getPackageLPr(pkg.getPackageName());
25807         }
25808         final String volumeUuid = pkg.getVolumeUuid();
25809         final String packageName = pkg.getPackageName();
25810 
25811         final int appId = UserHandle.getAppId(pkg.getUid());
25812 
25813         String pkgSeInfo = AndroidPackageUtils.getSeInfo(pkg, ps);
25814 
25815         Preconditions.checkNotNull(pkgSeInfo);
25816 
25817         final String seInfo = pkgSeInfo + (pkg.getSeInfoUser() != null ? pkg.getSeInfoUser() : "");
25818         final int targetSdkVersion = pkg.getTargetSdkVersion();
25819 
25820         return batch.createAppData(volumeUuid, packageName, userId, flags, appId, seInfo,
25821                 targetSdkVersion).whenComplete((ceDataInode, e) -> {
25822                     // Note: this code block is executed with the Installer lock
25823                     // already held, since it's invoked as a side-effect of
25824                     // executeBatchLI()
25825                     if (e != null) {
25826                         logCriticalInfo(Log.WARN, "Failed to create app data for " + packageName
25827                                 + ", but trying to recover: " + e);
25828                         destroyAppDataLeafLIF(pkg, userId, flags);
25829                         try {
25830                             ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId,
25831                                     flags, appId, seInfo, pkg.getTargetSdkVersion());
25832                             logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
25833                         } catch (InstallerException e2) {
25834                             logCriticalInfo(Log.DEBUG, "Recovery failed!");
25835                         }
25836                     } else if (e != null) {
25837                         Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
25838                     }
25839 
25840                     // Prepare the application profiles only for upgrades and
25841                     // first boot (so that we don't repeat the same operation at
25842                     // each boot).
25843                     //
25844                     // We only have to cover the upgrade and first boot here
25845                     // because for app installs we prepare the profiles before
25846                     // invoking dexopt (in installPackageLI).
25847                     //
25848                     // We also have to cover non system users because we do not
25849                     // call the usual install package methods for them.
25850                     //
25851                     // NOTE: in order to speed up first boot time we only create
25852                     // the current profile and do not update the content of the
25853                     // reference profile. A system image should already be
25854                     // configured with the right profile keys and the profiles
25855                     // for the speed-profile prebuilds should already be copied.
25856                     // That's done in #performDexOptUpgrade.
25857                     //
25858                     // TODO(calin, mathieuc): We should use .dm files for
25859                     // prebuilds profiles instead of manually copying them in
25860                     // #performDexOptUpgrade. When we do that we should have a
25861                     // more granular check here and only update the existing
25862                     // profiles.
25863                     if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) {
25864                         mArtManagerService.prepareAppProfiles(pkg, userId,
25865                             /* updateReferenceProfileContent= */ false);
25866                     }
25867 
25868                     if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
25869                         // TODO: mark this structure as dirty so we persist it!
25870                         synchronized (mLock) {
25871                             if (ps != null) {
25872                                 ps.setCeDataInode(ceDataInode, userId);
25873                             }
25874                         }
25875                     }
25876 
25877                     prepareAppDataContentsLeafLIF(pkg, ps, userId, flags);
25878                 });
25879     }
25880 
25881     private void prepareAppDataContentsLIF(AndroidPackage pkg, @Nullable PackageSetting pkgSetting,
25882             int userId, int flags) {
25883         if (pkg == null) {
25884             Slog.wtf(TAG, "Package was null!", new Throwable());
25885             return;
25886         }
25887         prepareAppDataContentsLeafLIF(pkg, pkgSetting, userId, flags);
25888     }
25889 
25890     private void prepareAppDataContentsLeafLIF(AndroidPackage pkg,
25891             @Nullable PackageSetting pkgSetting, int userId, int flags) {
25892         final String volumeUuid = pkg.getVolumeUuid();
25893         final String packageName = pkg.getPackageName();
25894 
25895         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
25896             // Create a native library symlink only if we have native libraries
25897             // and if the native libraries are 32 bit libraries. We do not provide
25898             // this symlink for 64 bit libraries.
25899             String primaryCpuAbi = AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting);
25900             if (primaryCpuAbi != null && !VMRuntime.is64BitAbi(primaryCpuAbi)) {
25901                 final String nativeLibPath = pkg.getNativeLibraryDir();
25902                 try {
25903                     mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
25904                             nativeLibPath, userId);
25905                 } catch (InstallerException e) {
25906                     Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
25907                 }
25908             }
25909         }
25910     }
25911 
25912     /**
25913      * For system apps on non-FBE devices, this method migrates any existing
25914      * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
25915      * requested by the app.
25916      */
25917     private boolean maybeMigrateAppDataLIF(AndroidPackage pkg, int userId) {
25918         if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
25919                 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
25920             final int storageTarget = pkg.isDefaultToDeviceProtectedStorage()
25921                     ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
25922             try {
25923                 mInstaller.migrateAppData(pkg.getVolumeUuid(), pkg.getPackageName(), userId,
25924                         storageTarget);
25925             } catch (InstallerException e) {
25926                 logCriticalInfo(Log.WARN,
25927                         "Failed to migrate " + pkg.getPackageName() + ": " + e.getMessage());
25928             }
25929             return true;
25930         } else {
25931             return false;
25932         }
25933     }
25934 
25935     public PackageFreezer freezePackage(String packageName, String killReason) {
25936         return freezePackage(packageName, UserHandle.USER_ALL, killReason);
25937     }
25938 
25939     public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
25940         return new PackageFreezer(packageName, userId, killReason);
25941     }
25942 
25943     public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
25944             String killReason) {
25945         return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
25946     }
25947 
25948     public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
25949             String killReason) {
25950         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
25951             return new PackageFreezer();
25952         } else {
25953             return freezePackage(packageName, userId, killReason);
25954         }
25955     }
25956 
25957     public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
25958             String killReason) {
25959         return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
25960     }
25961 
25962     public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
25963             String killReason) {
25964         if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
25965             return new PackageFreezer();
25966         } else {
25967             return freezePackage(packageName, userId, killReason);
25968         }
25969     }
25970 
25971     /**
25972      * Class that freezes and kills the given package upon creation, and
25973      * unfreezes it upon closing. This is typically used when doing surgery on
25974      * app code/data to prevent the app from running while you're working.
25975      */
25976     private class PackageFreezer implements AutoCloseable {
25977         private final String mPackageName;
25978 
25979         private final boolean mWeFroze;
25980 
25981         private final AtomicBoolean mClosed = new AtomicBoolean();
25982         private final CloseGuard mCloseGuard = CloseGuard.get();
25983 
25984         /**
25985          * Create and return a stub freezer that doesn't actually do anything,
25986          * typically used when someone requested
25987          * {@link PackageManager#INSTALL_DONT_KILL_APP} or
25988          * {@link PackageManager#DELETE_DONT_KILL_APP}.
25989          */
25990         public PackageFreezer() {
25991             mPackageName = null;
25992             mWeFroze = false;
25993             mCloseGuard.open("close");
25994         }
25995 
25996         public PackageFreezer(String packageName, int userId, String killReason) {
25997             synchronized (mLock) {
25998                 mPackageName = packageName;
25999                 mWeFroze = mFrozenPackages.add(mPackageName);
26000 
26001                 final PackageSetting ps = mSettings.getPackageLPr(mPackageName);
26002                 if (ps != null) {
26003                     killApplication(ps.name, ps.appId, userId, killReason);
26004                 }
26005             }
26006             mCloseGuard.open("close");
26007         }
26008 
26009         @Override
26010         protected void finalize() throws Throwable {
26011             try {
26012                 mCloseGuard.warnIfOpen();
26013                 close();
26014             } finally {
26015                 super.finalize();
26016             }
26017         }
26018 
26019         @Override
26020         public void close() {
26021             mCloseGuard.close();
26022             if (mClosed.compareAndSet(false, true)) {
26023                 synchronized (mLock) {
26024                     if (mWeFroze) {
26025                         mFrozenPackages.remove(mPackageName);
26026                     }
26027                 }
26028             }
26029         }
26030     }
26031 
26032     /**
26033      * Verify that given package is currently frozen.
26034      */
26035     private void checkPackageFrozen(String packageName) {
26036         synchronized (mLock) {
26037             if (!mFrozenPackages.contains(packageName)) {
26038                 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
26039             }
26040         }
26041     }
26042 
26043     @Override
26044     public int movePackage(final String packageName, final String volumeUuid) {
26045         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
26046 
26047         final int callingUid = Binder.getCallingUid();
26048         final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
26049         final int moveId = mNextMoveId.getAndIncrement();
26050         mHandler.post(() -> {
26051             try {
26052                 movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
26053             } catch (PackageManagerException e) {
26054                 Slog.w(TAG, "Failed to move " + packageName, e);
26055                 mMoveCallbacks.notifyStatusChanged(moveId, e.error);
26056             }
26057         });
26058         return moveId;
26059     }
26060 
26061     private void movePackageInternal(final String packageName, final String volumeUuid,
26062             final int moveId, final int callingUid, UserHandle user)
26063                     throws PackageManagerException {
26064         final StorageManager storage = mInjector.getSystemService(StorageManager.class);
26065         final PackageManager pm = mContext.getPackageManager();
26066 
26067         final String currentVolumeUuid;
26068         final File codeFile;
26069         final InstallSource installSource;
26070         final String packageAbiOverride;
26071         final int appId;
26072         final String seinfo;
26073         final String label;
26074         final int targetSdkVersion;
26075         final PackageFreezer freezer;
26076         final int[] installedUserIds;
26077         final boolean isCurrentLocationExternal;
26078         final String fromCodePath;
26079 
26080         // reader
26081         synchronized (mLock) {
26082             final AndroidPackage pkg = mPackages.get(packageName);
26083             final PackageSetting ps = mSettings.getPackageLPr(packageName);
26084             if (pkg == null
26085                     || ps == null
26086                     || shouldFilterApplicationLocked(ps, callingUid, user.getIdentifier())) {
26087                 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
26088             }
26089             if (pkg.isSystem()) {
26090                 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
26091                         "Cannot move system application");
26092             }
26093 
26094             final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
26095             final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
26096                     com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
26097             if (isInternalStorage && !allow3rdPartyOnInternal) {
26098                 throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
26099                         "3rd party apps are not allowed on internal storage");
26100             }
26101 
26102             currentVolumeUuid = ps.volumeUuid;
26103 
26104             final File probe = new File(pkg.getPath());
26105             final File probeOat = new File(probe, "oat");
26106             if (!probe.isDirectory() || !probeOat.isDirectory()) {
26107                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
26108                         "Move only supported for modern cluster style installs");
26109             }
26110 
26111             if (Objects.equals(currentVolumeUuid, volumeUuid)) {
26112                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
26113                         "Package already moved to " + volumeUuid);
26114             }
26115             if (!pkg.isExternalStorage() && isPackageDeviceAdminOnAnyUser(packageName)) {
26116                 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
26117                         "Device admin cannot be moved");
26118             }
26119 
26120             if (mFrozenPackages.contains(packageName)) {
26121                 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
26122                         "Failed to move already frozen package");
26123             }
26124 
26125             isCurrentLocationExternal = pkg.isExternalStorage();
26126             codeFile = new File(pkg.getPath());
26127             installSource = ps.installSource;
26128             packageAbiOverride = ps.cpuAbiOverrideString;
26129             appId = UserHandle.getAppId(pkg.getUid());
26130             seinfo = AndroidPackageUtils.getSeInfo(pkg, ps);
26131             label = String.valueOf(pm.getApplicationLabel(pkg.toAppInfoWithoutState()));
26132             targetSdkVersion = pkg.getTargetSdkVersion();
26133             freezer = freezePackage(packageName, "movePackageInternal");
26134             installedUserIds = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
26135             if (codeFile.getParentFile().getName().startsWith(RANDOM_DIR_PREFIX)) {
26136                 fromCodePath = codeFile.getParentFile().getAbsolutePath();
26137             } else {
26138                 fromCodePath = codeFile.getAbsolutePath();
26139             }
26140         }
26141 
26142         final Bundle extras = new Bundle();
26143         extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
26144         extras.putString(Intent.EXTRA_TITLE, label);
26145         mMoveCallbacks.notifyCreated(moveId, extras);
26146 
26147         int installFlags;
26148         final boolean moveCompleteApp;
26149         final File measurePath;
26150 
26151         installFlags = INSTALL_INTERNAL;
26152         if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
26153             moveCompleteApp = true;
26154             measurePath = Environment.getDataAppDirectory(volumeUuid);
26155         } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
26156             moveCompleteApp = false;
26157             measurePath = storage.getPrimaryPhysicalVolume().getPath();
26158         } else {
26159             final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
26160             if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
26161                     || !volume.isMountedWritable()) {
26162                 freezer.close();
26163                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
26164                         "Move location not mounted private volume");
26165             }
26166 
26167             moveCompleteApp = true;
26168             measurePath = Environment.getDataAppDirectory(volumeUuid);
26169         }
26170 
26171         // If we're moving app data around, we need all the users unlocked
26172         if (moveCompleteApp) {
26173             for (int userId : installedUserIds) {
26174                 if (StorageManager.isFileEncryptedNativeOrEmulated()
26175                         && !StorageManager.isUserKeyUnlocked(userId)) {
26176                     throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
26177                             "User " + userId + " must be unlocked");
26178                 }
26179             }
26180         }
26181 
26182         final PackageStats stats = new PackageStats(null, -1);
26183         synchronized (mInstaller) {
26184             for (int userId : installedUserIds) {
26185                 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
26186                     freezer.close();
26187                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
26188                             "Failed to measure package size");
26189                 }
26190             }
26191         }
26192 
26193         if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
26194                 + stats.dataSize);
26195 
26196         final long startFreeBytes = measurePath.getUsableSpace();
26197         final long sizeBytes;
26198         if (moveCompleteApp) {
26199             sizeBytes = stats.codeSize + stats.dataSize;
26200         } else {
26201             sizeBytes = stats.codeSize;
26202         }
26203 
26204         if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
26205             freezer.close();
26206             throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
26207                     "Not enough free space to move");
26208         }
26209 
26210         mMoveCallbacks.notifyStatusChanged(moveId, 10);
26211 
26212         final CountDownLatch installedLatch = new CountDownLatch(1);
26213         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
26214             @Override
26215             public void onUserActionRequired(Intent intent) throws RemoteException {
26216                 throw new IllegalStateException();
26217             }
26218 
26219             @Override
26220             public void onPackageInstalled(String basePackageName, int returnCode, String msg,
26221                     Bundle extras) throws RemoteException {
26222                 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
26223                         + PackageManager.installStatusToString(returnCode, msg));
26224 
26225                 installedLatch.countDown();
26226                 freezer.close();
26227 
26228                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
26229                 switch (status) {
26230                     case PackageInstaller.STATUS_SUCCESS:
26231                         mMoveCallbacks.notifyStatusChanged(moveId,
26232                                 PackageManager.MOVE_SUCCEEDED);
26233                         logAppMovedStorage(packageName, isCurrentLocationExternal);
26234                         break;
26235                     case PackageInstaller.STATUS_FAILURE_STORAGE:
26236                         mMoveCallbacks.notifyStatusChanged(moveId,
26237                                 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
26238                         break;
26239                     default:
26240                         mMoveCallbacks.notifyStatusChanged(moveId,
26241                                 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
26242                         break;
26243                 }
26244             }
26245         };
26246 
26247         final MoveInfo move;
26248         if (moveCompleteApp) {
26249             // Kick off a thread to report progress estimates
26250             new Thread(() -> {
26251                 while (true) {
26252                     try {
26253                         if (installedLatch.await(1, TimeUnit.SECONDS)) {
26254                             break;
26255                         }
26256                     } catch (InterruptedException ignored) {
26257                     }
26258 
26259                     final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
26260                     final int progress = 10 + (int) MathUtils.constrain(
26261                             ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
26262                     mMoveCallbacks.notifyStatusChanged(moveId, progress);
26263                 }
26264             }).start();
26265 
26266             move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
26267                     appId, seinfo, targetSdkVersion, fromCodePath);
26268         } else {
26269             move = null;
26270         }
26271 
26272         installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
26273 
26274         final Message msg = mHandler.obtainMessage(INIT_COPY);
26275         final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
26276         final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
26277         final ParseResult<PackageLite> ret = ApkLiteParseUtils.parsePackageLite(input,
26278                 new File(origin.resolvedPath), /* flags */ 0);
26279         final PackageLite lite = ret.isSuccess() ? ret.getResult() : null;
26280         final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
26281                 installSource, volumeUuid, user, packageAbiOverride, lite);
26282         params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
26283         msg.obj = params;
26284 
26285         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
26286                 System.identityHashCode(msg.obj));
26287         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
26288                 System.identityHashCode(msg.obj));
26289 
26290         mHandler.sendMessage(msg);
26291     }
26292 
26293     /**
26294      * Logs that an app has been moved from internal to external storage and vice versa.
26295      * @param packageName The package that was moved.
26296      */
26297     private void logAppMovedStorage(String packageName, boolean isPreviousLocationExternal) {
26298         final AndroidPackage pkg;
26299         synchronized (mLock) {
26300             pkg = mPackages.get(packageName);
26301         }
26302         if (pkg == null) {
26303             return;
26304         }
26305 
26306         final StorageManager storage = mInjector.getSystemService(StorageManager.class);;
26307         VolumeInfo volume = storage.findVolumeByUuid(pkg.getStorageUuid().toString());
26308         int packageExternalStorageType = getPackageExternalStorageType(volume, pkg.isExternalStorage());
26309 
26310         if (!isPreviousLocationExternal && pkg.isExternalStorage()) {
26311             // Move from internal to external storage.
26312             FrameworkStatsLog.write(FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED,
26313                     packageExternalStorageType,
26314                     FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_EXTERNAL,
26315                     packageName);
26316         } else if (isPreviousLocationExternal && !pkg.isExternalStorage()) {
26317             // Move from external to internal storage.
26318             FrameworkStatsLog.write(FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED,
26319                     packageExternalStorageType,
26320                     FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_INTERNAL,
26321                     packageName);
26322         }
26323     }
26324 
26325     @Override
26326     public int movePrimaryStorage(String volumeUuid) throws RemoteException {
26327         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
26328 
26329         final int realMoveId = mNextMoveId.getAndIncrement();
26330         final Bundle extras = new Bundle();
26331         extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
26332         mMoveCallbacks.notifyCreated(realMoveId, extras);
26333 
26334         final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
26335             @Override
26336             public void onCreated(int moveId, Bundle extras) {
26337                 // Ignored
26338             }
26339 
26340             @Override
26341             public void onStatusChanged(int moveId, int status, long estMillis) {
26342                 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
26343             }
26344         };
26345 
26346         final StorageManager storage = mInjector.getSystemService(StorageManager.class);
26347         storage.setPrimaryStorageUuid(volumeUuid, callback);
26348         return realMoveId;
26349     }
26350 
26351     @Override
26352     public int getMoveStatus(int moveId) {
26353         mContext.enforceCallingOrSelfPermission(
26354                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
26355         return mMoveCallbacks.mLastStatus.get(moveId);
26356     }
26357 
26358     @Override
26359     public void registerMoveCallback(IPackageMoveObserver callback) {
26360         mContext.enforceCallingOrSelfPermission(
26361                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
26362         mMoveCallbacks.register(callback);
26363     }
26364 
26365     @Override
26366     public void unregisterMoveCallback(IPackageMoveObserver callback) {
26367         mContext.enforceCallingOrSelfPermission(
26368                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
26369         mMoveCallbacks.unregister(callback);
26370     }
26371 
26372     @Override
26373     public boolean setInstallLocation(int loc) {
26374         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
26375                 null);
26376         if (getInstallLocation() == loc) {
26377             return true;
26378         }
26379         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
26380                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
26381             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
26382                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
26383             return true;
26384         }
26385         return false;
26386    }
26387 
26388     @Override
26389     public int getInstallLocation() {
26390         // allow instant app access
26391         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
26392                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
26393                 PackageHelper.APP_INSTALL_AUTO);
26394     }
26395 
26396     /** Called by UserManagerService */
26397     void cleanUpUser(UserManagerService userManager, @UserIdInt int userId) {
26398         synchronized (mLock) {
26399             mDirtyUsers.remove(userId);
26400             mUserNeedsBadging.delete(userId);
26401             mPermissionManager.onUserRemoved(userId);
26402             mSettings.removeUserLPw(userId);
26403             mPendingBroadcasts.remove(userId);
26404             mInstantAppRegistry.onUserRemovedLPw(userId);
26405             removeUnusedPackagesLPw(userManager, userId);
26406         }
26407     }
26408 
26409     /**
26410      * We're removing userId and would like to remove any downloaded packages
26411      * that are no longer in use by any other user.
26412      * @param userId the user being removed
26413      */
26414     @GuardedBy("mLock")
26415     private void removeUnusedPackagesLPw(UserManagerService userManager, final int userId) {
26416         final boolean DEBUG_CLEAN_APKS = false;
26417         int [] users = userManager.getUserIds();
26418         final int numPackages = mSettings.getPackagesLocked().size();
26419         for (int index = 0; index < numPackages; index++) {
26420             final PackageSetting ps = mSettings.getPackagesLocked().valueAt(index);
26421             if (ps.pkg == null) {
26422                 continue;
26423             }
26424             final String packageName = ps.pkg.getPackageName();
26425             // Skip over if system app or static shared library
26426             if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0
26427                     || !TextUtils.isEmpty(ps.pkg.getStaticSharedLibName())) {
26428                 continue;
26429             }
26430             if (DEBUG_CLEAN_APKS) {
26431                 Slog.i(TAG, "Checking package " + packageName);
26432             }
26433             boolean keep = shouldKeepUninstalledPackageLPr(packageName);
26434             if (keep) {
26435                 if (DEBUG_CLEAN_APKS) {
26436                     Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
26437                 }
26438             } else {
26439                 for (int i = 0; i < users.length; i++) {
26440                     if (users[i] != userId && ps.getInstalled(users[i])) {
26441                         keep = true;
26442                         if (DEBUG_CLEAN_APKS) {
26443                             Slog.i(TAG, "  Keeping package " + packageName + " for user "
26444                                     + users[i]);
26445                         }
26446                         break;
26447                     }
26448                 }
26449             }
26450             if (!keep) {
26451                 if (DEBUG_CLEAN_APKS) {
26452                     Slog.i(TAG, "  Removing package " + packageName);
26453                 }
26454                 //end run
26455                 mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
26456                         userId, 0, true /*removedBySystem*/));
26457             }
26458         }
26459     }
26460 
26461     /**
26462      * Called by UserManagerService.
26463      *
26464      * @param userTypeInstallablePackages system packages that should be initially installed for
26465      *                                    this type of user, or {@code null} if all system packages
26466      *                                    should be installed
26467      * @param disallowedPackages packages that should not be initially installed. Takes precedence
26468      *                           over installablePackages.
26469      */
26470     void createNewUser(int userId, @Nullable Set<String> userTypeInstallablePackages,
26471             String[] disallowedPackages) {
26472         synchronized (mInstallLock) {
26473             mSettings.createNewUserLI(this, mInstaller, userId,
26474                     userTypeInstallablePackages, disallowedPackages);
26475         }
26476         synchronized (mLock) {
26477             scheduleWritePackageRestrictionsLocked(userId);
26478             scheduleWritePackageListLocked(userId);
26479             mAppsFilter.onUsersChanged();
26480         }
26481     }
26482 
26483     void onNewUserCreated(@UserIdInt int userId, boolean convertedFromPreCreated) {
26484         if (DEBUG_PERMISSIONS) {
26485             Slog.d(TAG, "onNewUserCreated(id=" + userId
26486                     + ", convertedFromPreCreated=" + convertedFromPreCreated + ")");
26487         }
26488         if (!convertedFromPreCreated || !readPermissionStateForUser(userId)) {
26489             mPermissionManager.onUserCreated(userId);
26490             mLegacyPermissionManager.grantDefaultPermissions(userId);
26491             mDomainVerificationManager.clearUser(userId);
26492         }
26493     }
26494 
26495     boolean readPermissionStateForUser(@UserIdInt int userId) {
26496         synchronized (mLock) {
26497             mPermissionManager.writeLegacyPermissionStateTEMP();
26498             mSettings.readPermissionStateForUserSyncLPr(userId);
26499             mPermissionManager.readLegacyPermissionStateTEMP();
26500             return mPmInternal.isPermissionUpgradeNeeded(userId);
26501         }
26502     }
26503 
26504     @Override
26505     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
26506         mContext.enforceCallingOrSelfPermission(
26507                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
26508                 "Only package verification agents can read the verifier device identity");
26509 
26510         synchronized (mLock) {
26511             return mSettings.getVerifierDeviceIdentityLPw();
26512         }
26513     }
26514 
26515     @Override
26516     public boolean isStorageLow() {
26517         // allow instant applications
26518         final long token = Binder.clearCallingIdentity();
26519         try {
26520             final DeviceStorageMonitorInternal
26521                     dsm = mInjector.getLocalService(DeviceStorageMonitorInternal.class);
26522             if (dsm != null) {
26523                 return dsm.isMemoryLow();
26524             } else {
26525                 return false;
26526             }
26527         } finally {
26528             Binder.restoreCallingIdentity(token);
26529         }
26530     }
26531 
26532     @Override
26533     public IPackageInstaller getPackageInstaller() {
26534         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
26535             return null;
26536         }
26537         return mInstallerService;
26538     }
26539 
26540     @Override
26541     public IArtManager getArtManager() {
26542         return mArtManagerService;
26543     }
26544 
26545     private boolean userNeedsBadging(int userId) {
26546         int index = mUserNeedsBadging.indexOfKey(userId);
26547         if (index < 0) {
26548             final UserInfo userInfo;
26549             final long token = Binder.clearCallingIdentity();
26550             try {
26551                 userInfo = mUserManager.getUserInfo(userId);
26552             } finally {
26553                 Binder.restoreCallingIdentity(token);
26554             }
26555             final boolean b;
26556             if (userInfo != null && userInfo.isManagedProfile()) {
26557                 b = true;
26558             } else {
26559                 b = false;
26560             }
26561             mUserNeedsBadging.put(userId, b);
26562             return b;
26563         }
26564         return mUserNeedsBadging.valueAt(index);
26565     }
26566 
26567     @Override
26568     public KeySet getKeySetByAlias(String packageName, String alias) {
26569         if (packageName == null || alias == null) {
26570             return null;
26571         }
26572         synchronized (mLock) {
26573             final AndroidPackage pkg = mPackages.get(packageName);
26574             if (pkg == null
26575                     || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
26576                     Binder.getCallingUid(), UserHandle.getCallingUserId())) {
26577                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
26578                 throw new IllegalArgumentException("Unknown package: " + packageName);
26579             }
26580             final KeySetManagerService ksms = mSettings.getKeySetManagerService();
26581             return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
26582         }
26583     }
26584 
26585     @Override
26586     public KeySet getSigningKeySet(String packageName) {
26587         if (packageName == null) {
26588             return null;
26589         }
26590         synchronized (mLock) {
26591             final int callingUid = Binder.getCallingUid();
26592             final int callingUserId = UserHandle.getUserId(callingUid);
26593             final AndroidPackage pkg = mPackages.get(packageName);
26594             if (pkg == null
26595                     || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
26596                     callingUid, callingUserId)) {
26597                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName
26598                         + ", uid:" + callingUid);
26599                 throw new IllegalArgumentException("Unknown package: " + packageName);
26600             }
26601             if (pkg.getUid() != callingUid
26602                     && Process.SYSTEM_UID != callingUid) {
26603                 throw new SecurityException("May not access signing KeySet of other apps.");
26604             }
26605             final KeySetManagerService ksms = mSettings.getKeySetManagerService();
26606             return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
26607         }
26608     }
26609 
26610     @Override
26611     public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
26612         final int callingUid = Binder.getCallingUid();
26613         if (getInstantAppPackageName(callingUid) != null) {
26614             return false;
26615         }
26616         if (packageName == null || ks == null) {
26617             return false;
26618         }
26619         synchronized (mLock) {
26620             final AndroidPackage pkg = mPackages.get(packageName);
26621             if (pkg == null
26622                     || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
26623                     callingUid, UserHandle.getUserId(callingUid))) {
26624                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
26625                 throw new IllegalArgumentException("Unknown package: " + packageName);
26626             }
26627             IBinder ksh = ks.getToken();
26628             if (ksh instanceof KeySetHandle) {
26629                 final KeySetManagerService ksms = mSettings.getKeySetManagerService();
26630                 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
26631             }
26632             return false;
26633         }
26634     }
26635 
26636     @Override
26637     public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
26638         final int callingUid = Binder.getCallingUid();
26639         if (getInstantAppPackageName(callingUid) != null) {
26640             return false;
26641         }
26642         if (packageName == null || ks == null) {
26643             return false;
26644         }
26645         synchronized (mLock) {
26646             final AndroidPackage pkg = mPackages.get(packageName);
26647             if (pkg == null
26648                     || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
26649                     callingUid, UserHandle.getUserId(callingUid))) {
26650                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
26651                 throw new IllegalArgumentException("Unknown package: " + packageName);
26652             }
26653             IBinder ksh = ks.getToken();
26654             if (ksh instanceof KeySetHandle) {
26655                 final KeySetManagerService ksms = mSettings.getKeySetManagerService();
26656                 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
26657             }
26658             return false;
26659         }
26660     }
26661 
26662     @GuardedBy("mLock")
26663     private void deletePackageIfUnusedLPr(final String packageName) {
26664         PackageSetting ps = mSettings.getPackageLPr(packageName);
26665         if (ps == null) {
26666             return;
26667         }
26668         if (!ps.isAnyInstalled(mUserManager.getUserIds())) {
26669             // TODO Implement atomic delete if package is unused
26670             // It is currently possible that the package will be deleted even if it is installed
26671             // after this method returns.
26672             mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
26673                     0, PackageManager.DELETE_ALL_USERS, true /*removedBySystem*/));
26674         }
26675     }
26676 
26677     private int verifyReplacingVersionCode(PackageInfoLite pkgLite,
26678             long requiredInstalledVersionCode, int installFlags) {
26679         String packageName = pkgLite.packageName;
26680         synchronized (mLock) {
26681             // Package which currently owns the data that the new package will own if installed.
26682             // If an app is uninstalled while keeping data (e.g. adb uninstall -k), installedPkg
26683             // will be null whereas dataOwnerPkg will contain information about the package
26684             // which was uninstalled while keeping its data.
26685             AndroidPackage dataOwnerPkg = mPackages.get(packageName);
26686             if (dataOwnerPkg  == null) {
26687                 PackageSetting ps = mSettings.getPackageLPr(packageName);
26688                 if (ps != null) {
26689                     dataOwnerPkg = ps.pkg;
26690                 }
26691             }
26692 
26693             if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST) {
26694                 if (dataOwnerPkg == null) {
26695                     Slog.w(TAG, "Required installed version code was "
26696                             + requiredInstalledVersionCode
26697                             + " but package is not installed");
26698                     return PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION;
26699                 }
26700 
26701                 if (dataOwnerPkg.getLongVersionCode() != requiredInstalledVersionCode) {
26702                     Slog.w(TAG, "Required installed version code was "
26703                             + requiredInstalledVersionCode
26704                             + " but actual installed version is "
26705                             + dataOwnerPkg.getLongVersionCode());
26706                     return PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION;
26707                 }
26708             }
26709 
26710             if (dataOwnerPkg != null) {
26711                 if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags,
26712                         dataOwnerPkg.isDebuggable())) {
26713                     try {
26714                         checkDowngrade(dataOwnerPkg, pkgLite);
26715                     } catch (PackageManagerException e) {
26716                         Slog.w(TAG, "Downgrade detected: " + e.getMessage());
26717                         return PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
26718                     }
26719                 }
26720             }
26721         }
26722         return PackageManager.INSTALL_SUCCEEDED;
26723     }
26724 
26725     /**
26726      * Check and throw if the given before/after packages would be considered a
26727      * downgrade.
26728      */
26729     private static void checkDowngrade(AndroidPackage before, PackageInfoLite after)
26730             throws PackageManagerException {
26731         if (after.getLongVersionCode() < before.getLongVersionCode()) {
26732             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
26733                     "Update version code " + after.versionCode + " is older than current "
26734                     + before.getLongVersionCode());
26735         } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
26736             if (after.baseRevisionCode < before.getBaseRevisionCode()) {
26737                 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
26738                         "Update base revision code " + after.baseRevisionCode
26739                         + " is older than current " + before.getBaseRevisionCode());
26740             }
26741 
26742             if (!ArrayUtils.isEmpty(after.splitNames)) {
26743                 for (int i = 0; i < after.splitNames.length; i++) {
26744                     final String splitName = after.splitNames[i];
26745                     final int j = ArrayUtils.indexOf(before.getSplitNames(), splitName);
26746                     if (j != -1) {
26747                         if (after.splitRevisionCodes[i] < before.getSplitRevisionCodes()[j]) {
26748                             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
26749                                     "Update split " + splitName + " revision code "
26750                                     + after.splitRevisionCodes[i] + " is older than current "
26751                                     + before.getSplitRevisionCodes()[j]);
26752                         }
26753                     }
26754                 }
26755             }
26756         }
26757     }
26758 
26759     private static class MoveCallbacks extends Handler {
26760         private static final int MSG_CREATED = 1;
26761         private static final int MSG_STATUS_CHANGED = 2;
26762 
26763         private final RemoteCallbackList<IPackageMoveObserver>
26764                 mCallbacks = new RemoteCallbackList<>();
26765 
26766         private final SparseIntArray mLastStatus = new SparseIntArray();
26767 
26768         public MoveCallbacks(Looper looper) {
26769             super(looper);
26770         }
26771 
26772         public void register(IPackageMoveObserver callback) {
26773             mCallbacks.register(callback);
26774         }
26775 
26776         public void unregister(IPackageMoveObserver callback) {
26777             mCallbacks.unregister(callback);
26778         }
26779 
26780         @Override
26781         public void handleMessage(Message msg) {
26782             final SomeArgs args = (SomeArgs) msg.obj;
26783             final int n = mCallbacks.beginBroadcast();
26784             for (int i = 0; i < n; i++) {
26785                 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
26786                 try {
26787                     invokeCallback(callback, msg.what, args);
26788                 } catch (RemoteException ignored) {
26789                 }
26790             }
26791             mCallbacks.finishBroadcast();
26792             args.recycle();
26793         }
26794 
26795         private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
26796                 throws RemoteException {
26797             switch (what) {
26798                 case MSG_CREATED: {
26799                     callback.onCreated(args.argi1, (Bundle) args.arg2);
26800                     break;
26801                 }
26802                 case MSG_STATUS_CHANGED: {
26803                     callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
26804                     break;
26805                 }
26806             }
26807         }
26808 
26809         private void notifyCreated(int moveId, Bundle extras) {
26810             Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
26811 
26812             final SomeArgs args = SomeArgs.obtain();
26813             args.argi1 = moveId;
26814             args.arg2 = extras;
26815             obtainMessage(MSG_CREATED, args).sendToTarget();
26816         }
26817 
26818         private void notifyStatusChanged(int moveId, int status) {
26819             notifyStatusChanged(moveId, status, -1);
26820         }
26821 
26822         private void notifyStatusChanged(int moveId, int status, long estMillis) {
26823             Slog.v(TAG, "Move " + moveId + " status " + status);
26824 
26825             final SomeArgs args = SomeArgs.obtain();
26826             args.argi1 = moveId;
26827             args.argi2 = status;
26828             args.arg3 = estMillis;
26829             obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
26830 
26831             synchronized (mLastStatus) {
26832                 mLastStatus.put(moveId, status);
26833             }
26834         }
26835     }
26836 
26837     private final class PackageChangeObserverDeathRecipient implements IBinder.DeathRecipient {
26838         private final IPackageChangeObserver mObserver;
26839 
26840         PackageChangeObserverDeathRecipient(IPackageChangeObserver observer) {
26841             mObserver = observer;
26842         }
26843 
26844         @Override
26845         public void binderDied() {
26846             synchronized (mPackageChangeObservers) {
26847                 mPackageChangeObservers.remove(mObserver);
26848                 Log.d(TAG, "Size of mPackageChangeObservers after removing dead observer is "
26849                     + mPackageChangeObservers.size());
26850             }
26851         }
26852     }
26853 
26854     private class PackageManagerNative extends IPackageManagerNative.Stub {
26855         @Override
26856         public void registerPackageChangeObserver(@NonNull IPackageChangeObserver observer) {
26857           synchronized (mPackageChangeObservers) {
26858             try {
26859                 observer.asBinder().linkToDeath(
26860                     new PackageChangeObserverDeathRecipient(observer), 0);
26861             } catch (RemoteException e) {
26862               Log.e(TAG, e.getMessage());
26863             }
26864             mPackageChangeObservers.add(observer);
26865             Log.d(TAG, "Size of mPackageChangeObservers after registry is "
26866                 + mPackageChangeObservers.size());
26867           }
26868         }
26869 
26870         @Override
26871         public void unregisterPackageChangeObserver(@NonNull IPackageChangeObserver observer) {
26872           synchronized (mPackageChangeObservers) {
26873             mPackageChangeObservers.remove(observer);
26874             Log.d(TAG, "Size of mPackageChangeObservers after unregistry is "
26875                 + mPackageChangeObservers.size());
26876           }
26877         }
26878 
26879         @Override
26880         public String[] getAllPackages() {
26881             return PackageManagerService.this.getAllPackages().toArray(new String[0]);
26882         }
26883 
26884         @Override
26885         public String[] getNamesForUids(int[] uids) throws RemoteException {
26886             String[] names = null;
26887             String[] results = null;
26888             try {
26889                 if (uids == null || uids.length == 0) {
26890                     return null;
26891                 }
26892                 names = PackageManagerService.this.getNamesForUids(uids);
26893                 results = (names != null) ? names : new String[uids.length];
26894                 // massage results so they can be parsed by the native binder
26895                 for (int i = results.length - 1; i >= 0; --i) {
26896                     if (results[i] == null) {
26897                         results[i] = "";
26898                     }
26899                 }
26900                 return results;
26901             } catch (Throwable t) {
26902                 // STOPSHIP(186558987): revert addition of try/catch/log
26903                 Slog.e(TAG, "uids: " + Arrays.toString(uids));
26904                 Slog.e(TAG, "names: " + Arrays.toString(names));
26905                 Slog.e(TAG, "results: " + Arrays.toString(results));
26906                 Slog.e(TAG, "throwing exception", t);
26907                 throw t;
26908             }
26909         }
26910 
26911         // NB: this differentiates between preloads and sideloads
26912         @Override
26913         public String getInstallerForPackage(String packageName) throws RemoteException {
26914             final String installerName = getInstallerPackageName(packageName);
26915             if (!TextUtils.isEmpty(installerName)) {
26916                 return installerName;
26917             }
26918             // differentiate between preload and sideload
26919             int callingUser = UserHandle.getUserId(Binder.getCallingUid());
26920             ApplicationInfo appInfo = getApplicationInfo(packageName,
26921                                     /*flags*/ 0,
26922                                     /*userId*/ callingUser);
26923             if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
26924                 return "preload";
26925             }
26926             return "";
26927         }
26928 
26929         @Override
26930         public long getVersionCodeForPackage(String packageName) throws RemoteException {
26931             try {
26932                 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
26933                 PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
26934                 if (pInfo != null) {
26935                     return pInfo.getLongVersionCode();
26936                 }
26937             } catch (Exception e) {
26938             }
26939             return 0;
26940         }
26941 
26942         @Override
26943         public int getTargetSdkVersionForPackage(String packageName) throws RemoteException {
26944             int targetSdk = getTargetSdkVersion(packageName);
26945             if (targetSdk != -1) {
26946                 return targetSdk;
26947             }
26948 
26949             throw new RemoteException("Couldn't get targetSdkVersion for package " + packageName);
26950         }
26951 
26952         @Override
26953         public boolean isPackageDebuggable(String packageName) throws RemoteException {
26954             int callingUser = UserHandle.getCallingUserId();
26955             ApplicationInfo appInfo = getApplicationInfo(packageName, 0, callingUser);
26956             if (appInfo != null) {
26957                 return (0 != (appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE));
26958             }
26959 
26960             throw new RemoteException("Couldn't get debug flag for package " + packageName);
26961         }
26962 
26963         @Override
26964         public boolean[] isAudioPlaybackCaptureAllowed(String[] packageNames)
26965                 throws RemoteException {
26966             int callingUser = UserHandle.getUserId(Binder.getCallingUid());
26967             boolean[] results = new boolean[packageNames.length];
26968             for (int i = results.length - 1; i >= 0; --i) {
26969                 ApplicationInfo appInfo = getApplicationInfo(packageNames[i], 0, callingUser);
26970                 results[i] = appInfo == null ? false : appInfo.isAudioPlaybackCaptureAllowed();
26971             }
26972             return results;
26973         }
26974 
26975         @Override
26976         public int getLocationFlags(String packageName) throws RemoteException {
26977             int callingUser = UserHandle.getUserId(Binder.getCallingUid());
26978             ApplicationInfo appInfo = getApplicationInfo(packageName,
26979                     /*flags*/ 0,
26980                     /*userId*/ callingUser);
26981             if (appInfo == null) {
26982                 throw new RemoteException(
26983                         "Couldn't get ApplicationInfo for package " + packageName);
26984             }
26985             return ((appInfo.isSystemApp() ? IPackageManagerNative.LOCATION_SYSTEM : 0)
26986                     | (appInfo.isVendor() ? IPackageManagerNative.LOCATION_VENDOR : 0)
26987                     | (appInfo.isProduct() ? IPackageManagerNative.LOCATION_PRODUCT : 0));
26988         }
26989 
26990         @Override
26991         public String getModuleMetadataPackageName() throws RemoteException {
26992             return PackageManagerService.this.mModuleInfoProvider.getPackageName();
26993         }
26994 
26995         @Override
26996         public boolean hasSha256SigningCertificate(String packageName, byte[] certificate)
26997                 throws RemoteException {
26998             return PackageManagerService.this.hasSigningCertificate(
26999                 packageName, certificate, CERT_INPUT_SHA256);
27000         }
27001 
27002         @Override
27003         public boolean hasSystemFeature(String featureName, int version) {
27004             return PackageManagerService.this.hasSystemFeature(featureName, version);
27005         }
27006     }
27007 
27008     private AndroidPackage getPackage(String packageName) {
27009         return mComputer.getPackage(packageName);
27010     }
27011 
27012     private AndroidPackage getPackage(int uid) {
27013         return mComputer.getPackage(uid);
27014     }
27015 
27016     private SigningDetails getSigningDetails(@NonNull String packageName) {
27017         return mComputer.getSigningDetails(packageName);
27018     }
27019 
27020     private SigningDetails getSigningDetails(int uid) {
27021         return mComputer.getSigningDetails(uid);
27022     }
27023 
27024     private boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
27025         return mComputer.filterAppAccess(pkg, callingUid, userId);
27026     }
27027 
27028     private boolean filterAppAccess(String packageName, int callingUid, int userId) {
27029         return mComputer.filterAppAccess(packageName, callingUid, userId);
27030     }
27031 
27032     private class PackageManagerInternalImpl extends PackageManagerInternal {
27033         @Override
27034         public List<ApplicationInfo> getInstalledApplications(int flags, int userId,
27035                 int callingUid) {
27036             return PackageManagerService.this.getInstalledApplicationsListInternal(flags, userId,
27037                     callingUid);
27038         }
27039 
27040         @Override
27041         public boolean isPlatformSigned(String packageName) {
27042             PackageSetting packageSetting = mSettings.getPackageLPr(packageName);
27043             if (packageSetting == null) {
27044                 return false;
27045             }
27046             AndroidPackage pkg = packageSetting.pkg;
27047             if (pkg == null) {
27048                 // May happen if package in on a removable sd card
27049                 return false;
27050             }
27051             return pkg.getSigningDetails().hasAncestorOrSelf(mPlatformPackage.getSigningDetails())
27052                     || mPlatformPackage.getSigningDetails().checkCapability(pkg.getSigningDetails(),
27053                     PackageParser.SigningDetails.CertCapabilities.PERMISSION);
27054         }
27055 
27056         @Override
27057         public boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName) {
27058             SigningDetails sd = getSigningDetails(packageName);
27059             if (sd == null) {
27060                 return false;
27061             }
27062             return sd.hasSha256Certificate(restoringFromSigHash,
27063                     SigningDetails.CertCapabilities.INSTALLED_DATA);
27064         }
27065 
27066         @Override
27067         public boolean isDataRestoreSafe(Signature restoringFromSig, String packageName) {
27068             SigningDetails sd = getSigningDetails(packageName);
27069             if (sd == null) {
27070                 return false;
27071             }
27072             return sd.hasCertificate(restoringFromSig,
27073                     SigningDetails.CertCapabilities.INSTALLED_DATA);
27074         }
27075 
27076         @Override
27077         public boolean hasSignatureCapability(int serverUid, int clientUid,
27078                 @SigningDetails.CertCapabilities int capability) {
27079             SigningDetails serverSigningDetails = getSigningDetails(serverUid);
27080             SigningDetails clientSigningDetails = getSigningDetails(clientUid);
27081             return serverSigningDetails.checkCapability(clientSigningDetails, capability)
27082                     || clientSigningDetails.hasAncestorOrSelf(serverSigningDetails);
27083 
27084         }
27085 
27086         private SigningDetails getSigningDetails(@NonNull String packageName) {
27087             return PackageManagerService.this.getSigningDetails(packageName);
27088         }
27089 
27090         private SigningDetails getSigningDetails(int uid) {
27091             return PackageManagerService.this.getSigningDetails(uid);
27092         }
27093 
27094         @Override
27095         public boolean isInstantApp(String packageName, int userId) {
27096             return PackageManagerService.this.isInstantApp(packageName, userId);
27097         }
27098 
27099         @Override
27100         public String getInstantAppPackageName(int uid) {
27101             return PackageManagerService.this.getInstantAppPackageName(uid);
27102         }
27103 
27104         @Override
27105         public boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
27106             return PackageManagerService.this.filterAppAccess(pkg, callingUid, userId);
27107         }
27108 
27109         @Override
27110         public boolean filterAppAccess(String packageName, int callingUid, int userId) {
27111             return PackageManagerService.this.filterAppAccess(packageName, callingUid, userId);
27112         }
27113 
27114         @Override
27115         public AndroidPackage getPackage(String packageName) {
27116             return PackageManagerService.this.getPackage(packageName);
27117         }
27118 
27119         @Override
27120         public AndroidPackage getPackage(int uid) {
27121             return PackageManagerService.this.getPackage(uid);
27122         }
27123 
27124         @Nullable
27125         @Override
27126         public PackageSetting getPackageSetting(String packageName) {
27127             return PackageManagerService.this.getPackageSetting(packageName);
27128         }
27129 
27130         @Override
27131         public PackageList getPackageList(PackageListObserver observer) {
27132             synchronized (mLock) {
27133                 final int N = mPackages.size();
27134                 final ArrayList<String> list = new ArrayList<>(N);
27135                 for (int i = 0; i < N; i++) {
27136                     list.add(mPackages.keyAt(i));
27137                 }
27138                 final PackageList packageList = new PackageList(list, observer);
27139                 if (observer != null) {
27140                     mPackageListObservers.add(packageList);
27141                 }
27142                 return packageList;
27143             }
27144         }
27145 
27146         @Override
27147         public void removePackageListObserver(PackageListObserver observer) {
27148             synchronized (mLock) {
27149                 mPackageListObservers.remove(observer);
27150             }
27151         }
27152 
27153         @Override
27154         public PackageSetting getDisabledSystemPackage(@NonNull String packageName) {
27155             synchronized (mLock) {
27156                 return mSettings.getDisabledSystemPkgLPr(packageName);
27157             }
27158         }
27159 
27160         @Override
27161         public @Nullable
27162         String getDisabledSystemPackageName(@NonNull String packageName) {
27163             PackageSetting disabledPkgSetting = (PackageSetting) getDisabledSystemPackage(
27164                     packageName);
27165             AndroidPackage disabledPkg = disabledPkgSetting == null ? null : disabledPkgSetting.pkg;
27166             return disabledPkg == null ? null : disabledPkg.getPackageName();
27167         }
27168 
27169         /**
27170          * Only keep package names that refer to {@link PackageParser.Package#isSystem system}
27171          * packages.
27172          *
27173          * @param pkgNames The packages to filter
27174          *
27175          * @return The filtered packages
27176          */
27177         private @NonNull String[] filterOnlySystemPackages(@Nullable String... pkgNames) {
27178             if (pkgNames == null) {
27179                 return ArrayUtils.emptyArray(String.class);
27180             }
27181 
27182             ArrayList<String> systemPackageNames = new ArrayList<>(pkgNames.length);
27183 
27184             for (String pkgName: pkgNames) {
27185                 synchronized (mLock) {
27186                     if (pkgName == null) {
27187                         continue;
27188                     }
27189 
27190                     AndroidPackage pkg = getPackage(pkgName);
27191                     if (pkg == null) {
27192                         Log.w(TAG, "Could not find package " + pkgName);
27193                         continue;
27194                     }
27195 
27196                     if (!pkg.isSystem()) {
27197                         Log.w(TAG, pkgName + " is not system");
27198                         continue;
27199                     }
27200 
27201                     systemPackageNames.add(pkgName);
27202                 }
27203             }
27204 
27205             return systemPackageNames.toArray(new String[]{});
27206         }
27207 
27208         @Override
27209         public @NonNull String[] getKnownPackageNames(int knownPackage, int userId) {
27210             return getKnownPackageNamesInternal(knownPackage, userId);
27211         }
27212 
27213         private String[] getKnownPackageNamesInternal(int knownPackage, int userId) {
27214             switch (knownPackage) {
27215                 case PackageManagerInternal.PACKAGE_BROWSER:
27216                     return new String[] { mDefaultAppProvider.getDefaultBrowser(userId) };
27217                 case PackageManagerInternal.PACKAGE_INSTALLER:
27218                     return filterOnlySystemPackages(mRequiredInstallerPackage);
27219                 case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
27220                     return filterOnlySystemPackages(mSetupWizardPackage);
27221                 case PackageManagerInternal.PACKAGE_SYSTEM:
27222                     return new String[]{"android"};
27223                 case PackageManagerInternal.PACKAGE_VERIFIER:
27224                     return filterOnlySystemPackages(mRequiredVerifierPackage);
27225                 case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER:
27226                     return filterOnlySystemPackages(
27227                             mDefaultTextClassifierPackage, mSystemTextClassifierPackageName);
27228                 case PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER:
27229                     return filterOnlySystemPackages(mRequiredPermissionControllerPackage);
27230                 case PackageManagerInternal.PACKAGE_DOCUMENTER:
27231                     return filterOnlySystemPackages(mDocumenterPackage);
27232                 case PackageManagerInternal.PACKAGE_CONFIGURATOR:
27233                     return filterOnlySystemPackages(mConfiguratorPackage);
27234                 case PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER:
27235                     return filterOnlySystemPackages(mIncidentReportApproverPackage);
27236                 case PackageManagerInternal.PACKAGE_APP_PREDICTOR:
27237                     return filterOnlySystemPackages(mAppPredictionServicePackage);
27238                 case PackageManagerInternal.PACKAGE_COMPANION:
27239                     return filterOnlySystemPackages(COMPANION_PACKAGE_NAME);
27240                 case PackageManagerInternal.PACKAGE_RETAIL_DEMO:
27241                     return TextUtils.isEmpty(mRetailDemoPackage)
27242                             ? ArrayUtils.emptyArray(String.class)
27243                             : new String[] {mRetailDemoPackage};
27244                 case PackageManagerInternal.PACKAGE_OVERLAY_CONFIG_SIGNATURE:
27245                     return filterOnlySystemPackages(getOverlayConfigSignaturePackageName());
27246                 case PackageManagerInternal.PACKAGE_RECENTS:
27247                     return filterOnlySystemPackages(mRecentsPackage);
27248                 default:
27249                     return ArrayUtils.emptyArray(String.class);
27250             }
27251         }
27252 
27253         @Override
27254         public boolean isResolveActivityComponent(ComponentInfo component) {
27255             return mResolveActivity.packageName.equals(component.packageName)
27256                     && mResolveActivity.name.equals(component.name);
27257         }
27258 
27259         @Override
27260         public void setKeepUninstalledPackages(final List<String> packageList) {
27261             PackageManagerService.this.setKeepUninstalledPackagesInternal(packageList);
27262         }
27263 
27264         @Override
27265         public boolean isPermissionsReviewRequired(String packageName, int userId) {
27266             return mPermissionManager.isPermissionsReviewRequired(packageName, userId);
27267         }
27268 
27269         @Override
27270         public PackageInfo getPackageInfo(
27271                 String packageName, int flags, int filterCallingUid, int userId) {
27272             return PackageManagerService.this
27273                     .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
27274                             flags, filterCallingUid, userId);
27275         }
27276 
27277         @Override
27278         public long getCeDataInode(String packageName, int userId) {
27279             synchronized (mLock) {
27280                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
27281                 if (ps != null) {
27282                     return ps.getCeDataInode(userId);
27283                 }
27284                 return 0;
27285             }
27286         }
27287 
27288         @Override
27289         public Bundle getSuspendedPackageLauncherExtras(String packageName, int userId) {
27290             synchronized (mLock) {
27291                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
27292                 final Bundle allExtras = new Bundle();
27293                 if (ps != null) {
27294                     final PackageUserState pus = ps.readUserState(userId);
27295                     if (pus.suspended) {
27296                         for (int i = 0; i < pus.suspendParams.size(); i++) {
27297                             final PackageUserState.SuspendParams params =
27298                                     pus.suspendParams.valueAt(i);
27299                             if (params != null && params.launcherExtras != null) {
27300                                 allExtras.putAll(params.launcherExtras);
27301                             }
27302                         }
27303                     }
27304 
27305                 }
27306                 return (allExtras.size() > 0) ? allExtras : null;
27307             }
27308         }
27309 
27310         @Override
27311         public boolean isPackageSuspended(String packageName, int userId) {
27312             synchronized (mLock) {
27313                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
27314                 return (ps != null) ? ps.getSuspended(userId) : false;
27315             }
27316         }
27317 
27318         @Override
27319         public void removeAllNonSystemPackageSuspensions(int userId) {
27320             final String[] allPackages;
27321             synchronized (mLock) {
27322                 allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
27323             }
27324             PackageManagerService.this.removeSuspensionsBySuspendingPackage(allPackages,
27325                     (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
27326                     userId);
27327         }
27328 
27329         @Override
27330         public void removeNonSystemPackageSuspensions(String packageName, int userId) {
27331             PackageManagerService.this.removeSuspensionsBySuspendingPackage(
27332                     new String[]{packageName},
27333                     (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
27334                     userId);
27335         }
27336 
27337         @Override
27338         public void flushPackageRestrictions(int userId) {
27339             synchronized (mLock) {
27340                 PackageManagerService.this.flushPackageRestrictionsAsUserInternalLocked(userId);
27341             }
27342         }
27343 
27344         @Override
27345         public void removeDistractingPackageRestrictions(String packageName, int userId) {
27346             PackageManagerService.this.removeDistractingPackageRestrictions(
27347                     new String[]{packageName}, userId);
27348         }
27349 
27350         @Override
27351         public void removeAllDistractingPackageRestrictions(int userId) {
27352             PackageManagerService.this.removeAllDistractingPackageRestrictions(userId);
27353         }
27354 
27355         @Override
27356         public String getSuspendingPackage(String suspendedPackage, int userId) {
27357             synchronized (mLock) {
27358                 final PackageSetting ps = mSettings.getPackageLPr(suspendedPackage);
27359                 if (ps != null) {
27360                     final PackageUserState pus = ps.readUserState(userId);
27361                     if (pus.suspended) {
27362                         String suspendingPackage = null;
27363                         for (int i = 0; i < pus.suspendParams.size(); i++) {
27364                             suspendingPackage = pus.suspendParams.keyAt(i);
27365                             if (PLATFORM_PACKAGE_NAME.equals(suspendingPackage)) {
27366                                 return suspendingPackage;
27367                             }
27368                         }
27369                         return suspendingPackage;
27370                     }
27371                 }
27372                 return null;
27373             }
27374         }
27375 
27376         @Override
27377         public SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage,
27378                 String suspendingPackage, int userId) {
27379             synchronized (mLock) {
27380                 final PackageSetting ps = mSettings.getPackageLPr(suspendedPackage);
27381                 if (ps != null) {
27382                     final PackageUserState pus = ps.readUserState(userId);
27383                     if (pus.suspended) {
27384                         final PackageUserState.SuspendParams suspendParams =
27385                                 pus.suspendParams.get(suspendingPackage);
27386                         return (suspendParams != null) ? suspendParams.dialogInfo : null;
27387                     }
27388                 }
27389             }
27390             return null;
27391         }
27392 
27393         @Override
27394         public int getDistractingPackageRestrictions(String packageName, int userId) {
27395             synchronized (mLock) {
27396                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
27397                 return (ps != null) ? ps.getDistractionFlags(userId) : RESTRICTION_NONE;
27398             }
27399         }
27400 
27401         @Override
27402         public int getPackageUid(String packageName, int flags, int userId) {
27403             return PackageManagerService.this
27404                     .getPackageUidInternal(packageName, flags, userId, Process.SYSTEM_UID);
27405         }
27406 
27407         @Override
27408         public ApplicationInfo getApplicationInfo(
27409                 String packageName, int flags, int filterCallingUid, int userId) {
27410             return PackageManagerService.this
27411                     .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
27412         }
27413 
27414         @Override
27415         public ActivityInfo getActivityInfo(
27416                 ComponentName component, int flags, int filterCallingUid, int userId) {
27417             return PackageManagerService.this
27418                     .getActivityInfoInternal(component, flags, filterCallingUid, userId);
27419         }
27420 
27421         @Override
27422         public List<ResolveInfo> queryIntentActivities(
27423                 Intent intent, String resolvedType, int flags, int filterCallingUid, int userId) {
27424             return PackageManagerService.this
27425                     .queryIntentActivitiesInternal(intent, resolvedType, flags, 0, filterCallingUid,
27426                             userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
27427         }
27428 
27429         @Override
27430         public List<ResolveInfo> queryIntentServices(
27431                 Intent intent, int flags, int callingUid, int userId) {
27432             final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
27433             return PackageManagerService.this
27434                     .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
27435                             false);
27436         }
27437 
27438         @Override
27439         public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
27440                 int userId) {
27441             return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
27442         }
27443 
27444         @Override
27445         public ComponentName getDefaultHomeActivity(int userId) {
27446             return PackageManagerService.this.getDefaultHomeActivity(userId);
27447         }
27448 
27449         @Override
27450         public ComponentName getSystemUiServiceComponent() {
27451             return ComponentName.unflattenFromString(mContext.getResources().getString(
27452                     com.android.internal.R.string.config_systemUIServiceComponent));
27453         }
27454 
27455         @Override
27456         public void setDeviceAndProfileOwnerPackages(
27457                 int deviceOwnerUserId, String deviceOwnerPackage,
27458                 SparseArray<String> profileOwnerPackages) {
27459             mProtectedPackages.setDeviceAndProfileOwnerPackages(
27460                     deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
27461 
27462             final ArraySet<Integer> usersWithPoOrDo = new ArraySet<>();
27463             if (deviceOwnerPackage != null) {
27464                 usersWithPoOrDo.add(deviceOwnerUserId);
27465             }
27466             final int sz = profileOwnerPackages.size();
27467             for (int i = 0; i < sz; i++) {
27468                 if (profileOwnerPackages.valueAt(i) != null) {
27469                     usersWithPoOrDo.add(profileOwnerPackages.keyAt(i));
27470                 }
27471             }
27472         }
27473 
27474         @Override
27475         public void setDeviceOwnerProtectedPackages(
27476                 String deviceOwnerPackageName, List<String> packageNames) {
27477             mProtectedPackages.setDeviceOwnerProtectedPackages(
27478                     deviceOwnerPackageName, packageNames);
27479         }
27480 
27481         @Override
27482         public boolean isPackageDataProtected(int userId, String packageName) {
27483             return mProtectedPackages.isPackageDataProtected(userId, packageName);
27484         }
27485 
27486         @Override
27487         public boolean isPackageStateProtected(String packageName, int userId) {
27488             return mProtectedPackages.isPackageStateProtected(userId, packageName);
27489         }
27490 
27491         @Override
27492         public boolean isPackageEphemeral(int userId, String packageName) {
27493             synchronized (mLock) {
27494                 final PackageSetting ps = mSettings.getPackageLPr(packageName);
27495                 return ps != null ? ps.getInstantApp(userId) : false;
27496             }
27497         }
27498 
27499         @Override
27500         public boolean wasPackageEverLaunched(String packageName, int userId) {
27501             synchronized (mLock) {
27502                 return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
27503             }
27504         }
27505 
27506         // TODO(188814480) should be able to remove the NPE check when snapshot
27507         // "recursion" is fixed.
27508         @Override
27509         public boolean isEnabledAndMatches(ParsedMainComponent component, int flags, int userId) {
27510             synchronized (mLock) {
27511                 AndroidPackage pkg = getPackage(component.getPackageName());
27512                 if (pkg == null) {
27513                     return false;
27514                 } else {
27515                     return mSettings.isEnabledAndMatchLPr(pkg, component, flags, userId);
27516                 }
27517             }
27518         }
27519 
27520         @Override
27521         public boolean userNeedsBadging(int userId) {
27522             synchronized (mLock) {
27523                 return PackageManagerService.this.userNeedsBadging(userId);
27524             }
27525         }
27526 
27527         @Override
27528         public String getNameForUid(int uid) {
27529             return PackageManagerService.this.getNameForUid(uid);
27530         }
27531 
27532         @Override
27533         public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
27534                 Intent origIntent, String resolvedType, String callingPackage,
27535                 @Nullable String callingFeatureId, boolean isRequesterInstantApp,
27536                 Bundle verificationBundle, int userId) {
27537             PackageManagerService.this.requestInstantAppResolutionPhaseTwo(responseObj, origIntent,
27538                     resolvedType, callingPackage, callingFeatureId, isRequesterInstantApp,
27539                     verificationBundle, userId);
27540         }
27541 
27542         @Override
27543         public void grantImplicitAccess(int userId, Intent intent,
27544                 int recipientAppId, int visibleUid, boolean direct) {
27545             synchronized (mLock) {
27546                 final AndroidPackage visiblePackage = getPackage(visibleUid);
27547                 final int recipientUid = UserHandle.getUid(userId, recipientAppId);
27548                 if (visiblePackage == null || getPackage(recipientUid) == null) {
27549                     return;
27550                 }
27551 
27552                 final boolean instantApp =
27553                         isInstantAppInternal(visiblePackage.getPackageName(), userId, visibleUid);
27554                 final boolean accessGranted;
27555                 if (instantApp) {
27556                     if (!direct) {
27557                         // if the interaction that lead to this granting access to an instant app
27558                         // was indirect (i.e.: URI permission grant), do not actually execute the
27559                         // grant.
27560                         return;
27561                     }
27562                     accessGranted = mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
27563                             recipientAppId, UserHandle.getAppId(visibleUid) /*instantAppId*/);
27564                 } else {
27565                     accessGranted = mAppsFilter.grantImplicitAccess(recipientUid, visibleUid);
27566                 }
27567                 if (accessGranted) {
27568                     ApplicationPackageManager.invalidateGetPackagesForUidCache();
27569                 }
27570             }
27571         }
27572 
27573         @Override
27574         public boolean isInstantAppInstallerComponent(ComponentName component) {
27575             synchronized (mLock) {
27576                 return mInstantAppInstallerActivity != null
27577                         && mInstantAppInstallerActivity.getComponentName().equals(component);
27578             }
27579         }
27580 
27581         @Override
27582         public void pruneInstantApps() {
27583             mInstantAppRegistry.pruneInstantApps();
27584         }
27585 
27586         @Override
27587         public void pruneCachedApksInApex(@NonNull List<PackageInfo> apexPackages) {
27588             if (mCacheDir == null) {
27589                 return;
27590             }
27591 
27592             final PackageCacher cacher = new PackageCacher(mCacheDir);
27593             synchronized (mLock) {
27594                 for (int i = 0, size = apexPackages.size(); i < size; i++) {
27595                     final List<String> apkNames =
27596                             mApexManager.getApksInApex(apexPackages.get(i).packageName);
27597                     for (int j = 0, apksInApex = apkNames.size(); j < apksInApex; j++) {
27598                         final AndroidPackage pkg = getPackage(apkNames.get(j));
27599                         cacher.cleanCachedResult(new File(pkg.getPath()));
27600                     }
27601                 }
27602             }
27603         }
27604 
27605         @Override
27606         public String getSetupWizardPackageName() {
27607             return mSetupWizardPackage;
27608         }
27609 
27610         public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
27611             if (policy != null) {
27612                 mExternalSourcesPolicy = policy;
27613             }
27614         }
27615 
27616         @Override
27617         public boolean isPackagePersistent(String packageName) {
27618             synchronized (mLock) {
27619                 AndroidPackage pkg = mPackages.get(packageName);
27620                 return pkg != null && pkg.isSystem() && pkg.isPersistent();
27621             }
27622         }
27623 
27624         @Override
27625         public List<PackageInfo> getOverlayPackages(int userId) {
27626             final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
27627             synchronized (mLock) {
27628                 for (AndroidPackage p : mPackages.values()) {
27629                     if (p.getOverlayTarget() != null) {
27630                         PackageInfo pkg = generatePackageInfo(getPackageSetting(p.getPackageName()),
27631                                 0, userId);
27632                         if (pkg != null) {
27633                             overlayPackages.add(pkg);
27634                         }
27635                     }
27636                 }
27637             }
27638             return overlayPackages;
27639         }
27640 
27641         @Override
27642         public List<String> getTargetPackageNames(int userId) {
27643             List<String> targetPackages = new ArrayList<>();
27644             synchronized (mLock) {
27645                 for (AndroidPackage p : mPackages.values()) {
27646                     if (p.getOverlayTarget() == null) {
27647                         targetPackages.add(p.getPackageName());
27648                     }
27649                 }
27650             }
27651             return targetPackages;
27652         }
27653 
27654         @Override
27655         public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
27656                 @Nullable OverlayPaths overlayPaths,
27657                 @NonNull Set<String> outUpdatedPackageNames) {
27658             boolean modified = false;
27659             synchronized (mLock) {
27660                 final AndroidPackage targetPkg = mPackages.get(targetPackageName);
27661                 if (targetPackageName == null || targetPkg == null) {
27662                     Slog.e(TAG, "failed to find package " + targetPackageName);
27663                     return false;
27664                 }
27665 
27666                 if (targetPkg.getLibraryNames() != null) {
27667                     // Set the overlay paths for dependencies of the shared library.
27668                     for (final String libName : targetPkg.getLibraryNames()) {
27669                         final SharedLibraryInfo info = getSharedLibraryInfoLPr(libName,
27670                                 SharedLibraryInfo.VERSION_UNDEFINED);
27671                         if (info == null) {
27672                             continue;
27673                         }
27674                         final List<VersionedPackage> dependents = getPackagesUsingSharedLibraryLPr(
27675                                 info, 0, Process.SYSTEM_UID, userId);
27676                         if (dependents == null) {
27677                             continue;
27678                         }
27679                         for (final VersionedPackage dependent : dependents) {
27680                             final PackageSetting ps = mSettings.getPackageLPr(
27681                                     dependent.getPackageName());
27682                             if (ps == null) {
27683                                 continue;
27684                             }
27685                             if (ps.setOverlayPathsForLibrary(libName, overlayPaths, userId)) {
27686                                 outUpdatedPackageNames.add(dependent.getPackageName());
27687                                 modified = true;
27688                             }
27689                         }
27690                     }
27691                 }
27692 
27693                 final PackageSetting ps = mSettings.getPackageLPr(targetPackageName);
27694                 if (ps.setOverlayPaths(overlayPaths, userId)) {
27695                     outUpdatedPackageNames.add(targetPackageName);
27696                     modified = true;
27697                 }
27698 
27699                 if (modified) {
27700                     invalidatePackageInfoCache();
27701                 }
27702             }
27703 
27704             return true;
27705         }
27706 
27707         @Override
27708         public ResolveInfo resolveIntent(Intent intent, String resolvedType,
27709                 int flags, int privateResolveFlags, int userId, boolean resolveForStart,
27710                 int filterCallingUid) {
27711             return resolveIntentInternal(
27712                     intent, resolvedType, flags, privateResolveFlags, userId, resolveForStart,
27713                     filterCallingUid);
27714         }
27715 
27716         @Override
27717         public ResolveInfo resolveService(Intent intent, String resolvedType,
27718                 int flags, int userId, int callingUid) {
27719             return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
27720         }
27721 
27722         @Override
27723         public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
27724             return PackageManagerService.this.resolveContentProviderInternal(
27725                     name, flags, userId);
27726         }
27727 
27728         @Override
27729         public ProviderInfo resolveContentProvider(String name, int flags, int userId,
27730                 int callingUid) {
27731             return PackageManagerService.this.resolveContentProviderInternal(
27732                     name, flags, userId, callingUid);
27733         }
27734 
27735         @Override
27736         public void addIsolatedUid(int isolatedUid, int ownerUid) {
27737             synchronized (mLock) {
27738                 mIsolatedOwners.put(isolatedUid, ownerUid);
27739             }
27740         }
27741 
27742         @Override
27743         public void removeIsolatedUid(int isolatedUid) {
27744             synchronized (mLock) {
27745                 mIsolatedOwners.delete(isolatedUid);
27746             }
27747         }
27748 
27749         @Override
27750         public int getUidTargetSdkVersion(int uid) {
27751             synchronized (mLock) {
27752                 return getUidTargetSdkVersionLockedLPr(uid);
27753             }
27754         }
27755 
27756         @Override
27757         public int getPackageTargetSdkVersion(String packageName) {
27758             synchronized (mLock) {
27759                 return getPackageTargetSdkVersionLockedLPr(packageName);
27760             }
27761         }
27762 
27763         @Override
27764         public boolean canAccessInstantApps(int callingUid, int userId) {
27765             return PackageManagerService.this.canViewInstantApps(callingUid, userId);
27766         }
27767 
27768         @Override
27769         public boolean canAccessComponent(int callingUid, ComponentName component, int userId) {
27770             synchronized (mLock) {
27771                 final PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
27772                 return ps != null && !PackageManagerService.this.shouldFilterApplicationLocked(
27773                         ps, callingUid, component, TYPE_UNKNOWN, userId);
27774             }
27775         }
27776 
27777         @Override
27778         public boolean hasInstantApplicationMetadata(String packageName, int userId) {
27779             synchronized (mLock) {
27780                 return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
27781             }
27782         }
27783 
27784         @Override
27785         public void notifyPackageUse(String packageName, int reason) {
27786             synchronized (mLock) {
27787                 PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
27788             }
27789         }
27790 
27791         @Override
27792         public SparseArray<String> getAppsWithSharedUserIds() {
27793             synchronized (mLock) {
27794                 return getAppsWithSharedUserIdsLocked();
27795             }
27796         }
27797 
27798         @Override
27799         @NonNull
27800         public String[] getSharedUserPackagesForPackage(String packageName, int userId) {
27801             synchronized (mLock) {
27802                 return getSharedUserPackagesForPackageLocked(packageName, userId);
27803             }
27804         }
27805 
27806         @Override
27807         public ArrayMap<String, ProcessInfo> getProcessesForUid(int uid) {
27808             synchronized (mLock) {
27809                 return getProcessesForUidLocked(uid);
27810             }
27811         }
27812 
27813         @Override
27814         public int[] getPermissionGids(String permissionName, int userId) {
27815             return mPermissionManager.getPermissionGids(permissionName, userId);
27816         }
27817 
27818         @Override
27819         public boolean isOnlyCoreApps() {
27820             return PackageManagerService.this.isOnlyCoreApps();
27821         }
27822 
27823         @Override
27824         public void freeStorage(String volumeUuid, long bytes, int storageFlags)
27825                 throws IOException {
27826             PackageManagerService.this.freeStorage(volumeUuid, bytes, storageFlags);
27827         }
27828 
27829         @Override
27830         public void forEachPackage(Consumer<AndroidPackage> actionLocked) {
27831             PackageManagerService.this.forEachPackage(actionLocked);
27832         }
27833 
27834         @Override
27835         public void forEachPackageSetting(Consumer<PackageSetting> actionLocked) {
27836             synchronized (mLock) {
27837                 for (int index = 0; index < mSettings.getPackagesLocked().size(); index++) {
27838                     actionLocked.accept(mSettings.getPackagesLocked().valueAt(index));
27839                 }
27840             }
27841         }
27842 
27843         @Override
27844         public void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> actionLocked,
27845                 @UserIdInt int userId) {
27846             PackageManagerService.this.forEachInstalledPackage(actionLocked, userId);
27847         }
27848 
27849         @Override
27850         public ArraySet<String> getEnabledComponents(String packageName, int userId) {
27851             synchronized (mLock) {
27852                 PackageSetting setting = mSettings.getPackageLPr(packageName);
27853                 if (setting == null) {
27854                     return new ArraySet<>();
27855                 }
27856                 return setting.getEnabledComponents(userId);
27857             }
27858         }
27859 
27860         @Override
27861         public ArraySet<String> getDisabledComponents(String packageName, int userId) {
27862             synchronized (mLock) {
27863                 PackageSetting setting = mSettings.getPackageLPr(packageName);
27864                 if (setting == null) {
27865                     return new ArraySet<>();
27866                 }
27867                 return setting.getDisabledComponents(userId);
27868             }
27869         }
27870 
27871         @Override
27872         public @PackageManager.EnabledState int getApplicationEnabledState(
27873                 String packageName, int userId) {
27874             synchronized (mLock) {
27875                 PackageSetting setting = mSettings.getPackageLPr(packageName);
27876                 if (setting == null) {
27877                     return COMPONENT_ENABLED_STATE_DEFAULT;
27878                 }
27879                 return setting.getEnabled(userId);
27880             }
27881         }
27882 
27883         @Override
27884         public @PackageManager.EnabledState int getComponentEnabledSetting(
27885                 @NonNull ComponentName componentName, int callingUid, int userId) {
27886             return PackageManagerService.this.getComponentEnabledSettingInternal(componentName,
27887                     callingUid, userId);
27888         }
27889 
27890         @Override
27891         public void setEnableRollbackCode(int token, int enableRollbackCode) {
27892             PackageManagerService.this.setEnableRollbackCode(token, enableRollbackCode);
27893         }
27894 
27895         /**
27896          * Ask the package manager to compile layouts in the given package.
27897          */
27898         @Override
27899         public boolean compileLayouts(String packageName) {
27900             AndroidPackage pkg;
27901             synchronized (mLock) {
27902                 pkg = mPackages.get(packageName);
27903                 if (pkg == null) {
27904                     return false;
27905                 }
27906             }
27907             return mArtManagerService.compileLayouts(pkg);
27908         }
27909 
27910         @Override
27911         public void finishPackageInstall(int token, boolean didLaunch) {
27912             PackageManagerService.this.finishPackageInstall(token, didLaunch);
27913         }
27914 
27915         @Nullable
27916         @Override
27917         public String removeLegacyDefaultBrowserPackageName(int userId) {
27918             synchronized (mLock) {
27919                 return mSettings.removeDefaultBrowserPackageNameLPw(userId);
27920             }
27921         }
27922 
27923         @Override
27924         public boolean isApexPackage(String packageName) {
27925             return PackageManagerService.this.mApexManager.isApexPackage(packageName);
27926         }
27927 
27928         @Override
27929         public List<String> getApksInApex(String apexPackageName) {
27930             return PackageManagerService.this.mApexManager.getApksInApex(apexPackageName);
27931         }
27932 
27933         @Override
27934         public void uninstallApex(String packageName, long versionCode, int userId,
27935                 IntentSender intentSender, int flags) {
27936             final int callerUid = Binder.getCallingUid();
27937             if (callerUid != Process.ROOT_UID && callerUid != Process.SHELL_UID) {
27938                 throw new SecurityException("Not allowed to uninstall apexes");
27939             }
27940             PackageInstallerService.PackageDeleteObserverAdapter adapter =
27941                     new PackageInstallerService.PackageDeleteObserverAdapter(
27942                             PackageManagerService.this.mContext, intentSender, packageName,
27943                             false, userId);
27944             if ((flags & PackageManager.DELETE_ALL_USERS) == 0) {
27945                 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
27946                         "Can't uninstall an apex for a single user");
27947                 return;
27948             }
27949             final ApexManager am = PackageManagerService.this.mApexManager;
27950             PackageInfo activePackage = am.getPackageInfo(packageName,
27951                     ApexManager.MATCH_ACTIVE_PACKAGE);
27952             if (activePackage == null) {
27953                 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
27954                         packageName + " is not an apex package");
27955                 return;
27956             }
27957             if (versionCode != PackageManager.VERSION_CODE_HIGHEST
27958                     && activePackage.getLongVersionCode() != versionCode) {
27959                 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
27960                         "Active version " + activePackage.getLongVersionCode()
27961                                 + " is not equal to " + versionCode + "]");
27962                 return;
27963             }
27964             if (!am.uninstallApex(activePackage.applicationInfo.sourceDir)) {
27965                 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
27966                         "Failed to uninstall apex " + packageName);
27967             } else {
27968                 adapter.onPackageDeleted(packageName, PackageManager.DELETE_SUCCEEDED,
27969                         null);
27970             }
27971         }
27972 
27973         @Override
27974         public void updateRuntimePermissionsFingerprint(@UserIdInt int userId) {
27975             synchronized (mLock) {
27976                 mSettings.updateRuntimePermissionsFingerprintLPr(userId);
27977             }
27978         }
27979 
27980         @Override
27981         public void migrateLegacyObbData() {
27982             try {
27983                 mInstaller.migrateLegacyObbData();
27984             } catch (Exception e) {
27985                 Slog.wtf(TAG, e);
27986             }
27987         }
27988 
27989         @Override
27990         public void writeSettings(boolean async) {
27991             synchronized (mLock) {
27992                 if (async) {
27993                     scheduleWriteSettingsLocked();
27994                 } else {
27995                     writeSettingsLPrTEMP();
27996                 }
27997             }
27998         }
27999 
28000         @Override
28001         public void writePermissionSettings(int[] userIds, boolean async) {
28002             synchronized (mLock) {
28003                 for (int userId : userIds) {
28004                     mSettings.writePermissionStateForUserLPr(userId, !async);
28005                 }
28006             }
28007         }
28008 
28009         @Override
28010         public boolean isCallerInstallerOfRecord(
28011                 @NonNull AndroidPackage pkg, int callingUid) {
28012             synchronized (mLock) {
28013                 if (pkg == null) {
28014                     return false;
28015                 }
28016                 final PackageSetting packageSetting = getPackageSetting(pkg.getPackageName());
28017                 if (packageSetting == null) {
28018                     return false;
28019                 }
28020                 final PackageSetting installerPackageSetting =
28021                         mSettings.getPackageLPr(packageSetting.installSource.installerPackageName);
28022                 return installerPackageSetting != null
28023                         && UserHandle.isSameApp(installerPackageSetting.appId, callingUid);
28024             }
28025         }
28026 
28027         @Override
28028         public boolean isPermissionUpgradeNeeded(int userId) {
28029             synchronized (mLock) {
28030                 return mSettings.isPermissionUpgradeNeededLPr(userId);
28031             }
28032         }
28033 
28034         @Override
28035         public void setIntegrityVerificationResult(int verificationId, int verificationResult) {
28036             final Message msg = mHandler.obtainMessage(INTEGRITY_VERIFICATION_COMPLETE);
28037             msg.arg1 = verificationId;
28038             msg.obj = verificationResult;
28039             mHandler.sendMessage(msg);
28040         }
28041 
28042         @Override
28043         public List<String> getMimeGroup(String packageName, String mimeGroup) {
28044             return PackageManagerService.this.getMimeGroupInternal(packageName, mimeGroup);
28045         }
28046 
28047         @Override
28048         public void setVisibilityLogging(String packageName, boolean enable) {
28049             final PackageSetting pkg;
28050             synchronized (mLock) {
28051                 pkg = mSettings.getPackageLPr(packageName);
28052             }
28053             if (pkg == null) {
28054                 throw new IllegalStateException("No package found for " + packageName);
28055             }
28056             mAppsFilter.getFeatureConfig().enableLogging(pkg.appId, enable);
28057         }
28058 
28059         @Override
28060         public boolean isSystemPackage(@NonNull String packageName) {
28061             return packageName.equals(
28062                     PackageManagerService.this.ensureSystemPackageName(packageName));
28063         }
28064 
28065         @Override
28066         public void clearBlockUninstallForUser(@UserIdInt int userId) {
28067             synchronized (mLock) {
28068                 mSettings.clearBlockUninstallLPw(userId);
28069                 mSettings.writePackageRestrictionsLPr(userId);
28070             }
28071         }
28072 
28073         @Override
28074         public void unsuspendForSuspendingPackage(final String packageName, int affectedUser) {
28075             PackageManagerService.this.unsuspendForSuspendingPackage(packageName, affectedUser);
28076         }
28077 
28078         @Override
28079         public boolean isSuspendingAnyPackages(String suspendingPackage, int userId) {
28080             return PackageManagerService.this.isSuspendingAnyPackages(suspendingPackage, userId);
28081         }
28082 
28083         @Override
28084         public boolean registerInstalledLoadingProgressCallback(String packageName,
28085                 PackageManagerInternal.InstalledLoadingProgressCallback callback, int userId) {
28086             final PackageSetting ps = getPackageSettingForUser(packageName, Binder.getCallingUid(),
28087                     userId);
28088             if (ps == null) {
28089                 return false;
28090             }
28091             if (!ps.isPackageLoading()) {
28092                 Slog.w(TAG,
28093                         "Failed registering loading progress callback. Package is fully loaded.");
28094                 return false;
28095             }
28096             if (mIncrementalManager == null) {
28097                 Slog.w(TAG,
28098                         "Failed registering loading progress callback. Incremental is not enabled");
28099                 return false;
28100             }
28101             return mIncrementalManager.registerLoadingProgressCallback(ps.getPathString(),
28102                     (IPackageLoadingProgressCallback) callback.getBinder());
28103         }
28104 
28105         @Override
28106         public IncrementalStatesInfo getIncrementalStatesInfo(
28107                 @NonNull String packageName, int filterCallingUid, int userId) {
28108             final PackageSetting ps = getPackageSettingForUser(packageName, filterCallingUid,
28109                     userId);
28110             if (ps == null) {
28111                 return null;
28112             }
28113             return ps.getIncrementalStates();
28114         }
28115 
28116         @Override
28117         public void requestChecksums(@NonNull String packageName, boolean includeSplits,
28118                 @Checksum.TypeMask int optional, @Checksum.TypeMask int required,
28119                 @Nullable List trustedInstallers,
28120                 @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId,
28121                 @NonNull Executor executor, @NonNull Handler handler) {
28122             requestChecksumsInternal(packageName, includeSplits, optional, required,
28123                     trustedInstallers, onChecksumsReadyListener, userId, executor, handler);
28124         }
28125 
28126         @Override
28127         public boolean isPackageFrozen(@NonNull String packageName,
28128                 int callingUid, int userId) {
28129             return PackageManagerService.this.getPackageStartability(
28130                     packageName, callingUid, userId) == PACKAGE_STARTABILITY_FROZEN;
28131         }
28132 
28133         @Override
28134         public long deleteOatArtifactsOfPackage(String packageName) {
28135             return PackageManagerService.this.deleteOatArtifactsOfPackage(packageName);
28136         }
28137 
28138         @Override
28139         public void withPackageSettingsSnapshot(
28140                 @NonNull Consumer<Function<String, PackageSetting>> block) {
28141             final Computer snapshot = snapshotComputer();
28142 
28143             // This method needs to either lock or not lock consistently throughout the method,
28144             // so if the live computer is returned, force a wrapping sync block.
28145             if (snapshot == mLiveComputer) {
28146                 synchronized (mLock) {
28147                     block.accept(snapshot::getPackageSetting);
28148                 }
28149             } else {
28150                 block.accept(snapshot::getPackageSetting);
28151             }
28152         }
28153 
28154         @Override
28155         public <Output> Output withPackageSettingsSnapshotReturning(
28156                 @NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageSetting>, Output>
28157                         block) {
28158             final Computer snapshot = snapshotComputer();
28159 
28160             // This method needs to either lock or not lock consistently throughout the method,
28161             // so if the live computer is returned, force a wrapping sync block.
28162             if (snapshot == mLiveComputer) {
28163                 synchronized (mLock) {
28164                     return block.apply(snapshot::getPackageSetting);
28165                 }
28166             } else {
28167                 return block.apply(snapshot::getPackageSetting);
28168             }
28169         }
28170 
28171         @Override
28172         public <ExceptionType extends Exception> void withPackageSettingsSnapshotThrowing(
28173                 @NonNull FunctionalUtils.ThrowingCheckedConsumer<Function<String, PackageSetting>,
28174                         ExceptionType> block) throws ExceptionType {
28175             final Computer snapshot = snapshotComputer();
28176 
28177             // This method needs to either lock or not lock consistently throughout the method,
28178             // so if the live computer is returned, force a wrapping sync block.
28179             if (snapshot == mLiveComputer) {
28180                 synchronized (mLock) {
28181                     block.accept(snapshot::getPackageSetting);
28182                 }
28183             } else {
28184                 block.accept(snapshot::getPackageSetting);
28185             }
28186         }
28187 
28188         @Override
28189         public <ExceptionOne extends Exception, ExceptionTwo extends Exception> void
28190                 withPackageSettingsSnapshotThrowing2(
28191                         @NonNull FunctionalUtils.ThrowingChecked2Consumer<
28192                                 Function<String, PackageSetting>, ExceptionOne, ExceptionTwo> block)
28193                 throws ExceptionOne, ExceptionTwo {
28194             final Computer snapshot = snapshotComputer();
28195 
28196             // This method needs to either lock or not lock consistently throughout the method,
28197             // so if the live computer is returned, force a wrapping sync block.
28198             if (snapshot == mLiveComputer) {
28199                 synchronized (mLock) {
28200                     block.accept(snapshot::getPackageSetting);
28201                 }
28202             } else {
28203                 block.accept(snapshot::getPackageSetting);
28204             }
28205         }
28206 
28207         @Override
28208         public <Output, ExceptionType extends Exception> Output
28209                 withPackageSettingsSnapshotReturningThrowing(
28210                         @NonNull FunctionalUtils.ThrowingCheckedFunction<
28211                                 Function<String, PackageSetting>, Output, ExceptionType> block)
28212                 throws ExceptionType {
28213             final Computer snapshot = snapshotComputer();
28214 
28215             // This method needs to either lock or not lock consistently throughout the method,
28216             // so if the live computer is returned, force a wrapping sync block.
28217             if (snapshot == mLiveComputer) {
28218                 synchronized (mLock) {
28219                     return block.apply(snapshot::getPackageSetting);
28220                 }
28221             } else {
28222                 return block.apply(snapshot::getPackageSetting);
28223             }
28224         }
28225     }
28226 
28227     @GuardedBy("mLock")
28228     private SparseArray<String> getAppsWithSharedUserIdsLocked() {
28229         final SparseArray<String> sharedUserIds = new SparseArray<>();
28230         synchronized (mLock) {
28231             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
28232                 sharedUserIds.put(UserHandle.getAppId(setting.userId), setting.name);
28233             }
28234         }
28235         return sharedUserIds;
28236     }
28237 
28238     @GuardedBy("mLock")
28239     @NonNull
28240     private String[] getSharedUserPackagesForPackageLocked(String packageName, int userId) {
28241         final PackageSetting packageSetting = mSettings.getPackageLPr(packageName);
28242         if (packageSetting == null || !packageSetting.isSharedUser()) {
28243             return EmptyArray.STRING;
28244         }
28245 
28246         ArraySet<PackageSetting> packages = packageSetting.sharedUser.packages;
28247         final int numPackages = packages.size();
28248         String[] res = new String[numPackages];
28249         int i = 0;
28250         for (int index = 0; index < numPackages; index++) {
28251             final PackageSetting ps = packages.valueAt(index);
28252             if (ps.getInstalled(userId)) {
28253                 res[i++] = ps.name;
28254             }
28255         }
28256         res = ArrayUtils.trimToSize(res, i);
28257         return res != null ? res : EmptyArray.STRING;
28258     }
28259 
28260     @GuardedBy("mLock")
28261     public ArrayMap<String, ProcessInfo> getProcessesForUidLocked(int uid) {
28262         final int appId = UserHandle.getAppId(uid);
28263         final SettingBase obj = mSettings.getSettingLPr(appId);
28264         if (obj instanceof SharedUserSetting) {
28265             final SharedUserSetting sus = (SharedUserSetting) obj;
28266             return PackageInfoUtils.generateProcessInfo(sus.processes, 0);
28267         } else if (obj instanceof PackageSetting) {
28268             final PackageSetting ps = (PackageSetting) obj;
28269             return PackageInfoUtils.generateProcessInfo(ps.pkg.getProcesses(), 0);
28270         }
28271         return null;
28272     }
28273 
28274     @Override
28275     public int getRuntimePermissionsVersion(@UserIdInt int userId) {
28276         Preconditions.checkArgumentNonnegative(userId);
28277         enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
28278                 "getRuntimePermissionVersion");
28279         synchronized (mLock) {
28280             return mSettings.getDefaultRuntimePermissionsVersionLPr(userId);
28281         }
28282     }
28283 
28284     @Override
28285     public void setRuntimePermissionsVersion(int version, @UserIdInt int userId) {
28286         Preconditions.checkArgumentNonnegative(version);
28287         Preconditions.checkArgumentNonnegative(userId);
28288         enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
28289                 "setRuntimePermissionVersion");
28290         synchronized (mLock) {
28291             mSettings.setDefaultRuntimePermissionsVersionLPr(version, userId);
28292         }
28293     }
28294 
28295     private void enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
28296             @NonNull String message) {
28297         if (mContext.checkCallingOrSelfPermission(
28298                 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY)
28299                 != PackageManager.PERMISSION_GRANTED
28300                 && mContext.checkCallingOrSelfPermission(
28301                 Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS)
28302                 != PackageManager.PERMISSION_GRANTED) {
28303             throw new SecurityException(message + " requires "
28304                     + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " or "
28305                     + Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS);
28306         }
28307     }
28308 
28309     @Nullable
28310     public PackageSetting getPackageSetting(String packageName) {
28311         return mComputer.getPackageSetting(packageName);
28312     }
28313 
28314     private PackageSetting getPackageSettingInternal(String packageName, int callingUid) {
28315         return mComputer.getPackageSettingInternal(packageName, callingUid);
28316     }
28317 
28318     void forEachPackage(Consumer<AndroidPackage> actionLocked) {
28319         synchronized (mLock) {
28320             int numPackages = mPackages.size();
28321             for (int i = 0; i < numPackages; i++) {
28322                 actionLocked.accept(mPackages.valueAt(i));
28323             }
28324         }
28325     }
28326 
28327     void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> actionLocked,
28328             @UserIdInt int userId) {
28329         synchronized (mLock) {
28330             int numPackages = mPackages.size();
28331             for (int i = 0; i < numPackages; i++) {
28332                 AndroidPackage pkg = mPackages.valueAt(i);
28333                 PackageSetting setting = mSettings.getPackageLPr(pkg.getPackageName());
28334                 if (setting == null || !setting.getInstalled(userId)) {
28335                     continue;
28336                 }
28337                 actionLocked.accept(pkg);
28338             }
28339         }
28340     }
28341 
28342     boolean isHistoricalPackageUsageAvailable() {
28343         synchronized (mLock) {
28344             return mPackageUsage.isHistoricalPackageUsageAvailable();
28345         }
28346     }
28347 
28348     /**
28349      * Return a <b>copy</b> of the collection of packages known to the package manager.
28350      * @return A copy of the values of mPackages.
28351      */
28352     Collection<AndroidPackage> getPackages() {
28353         synchronized (mLock) {
28354             return new ArrayList<>(mPackages.values());
28355         }
28356     }
28357 
28358     /**
28359      * Logs process start information (including base APK hash) to the security log.
28360      * @hide
28361      */
28362     @Override
28363     public void logAppProcessStartIfNeeded(String packageName, String processName, int uid,
28364             String seinfo, String apkFile, int pid) {
28365         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
28366             return;
28367         }
28368         if (!SecurityLog.isLoggingEnabled()) {
28369             return;
28370         }
28371         mProcessLoggingHandler.logAppProcessStart(mContext, mPmInternal, apkFile, packageName,
28372                 processName, uid, seinfo, pid);
28373     }
28374 
28375     public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
28376         return mCompilerStats.getPackageStats(pkgName);
28377     }
28378 
28379     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(AndroidPackage pkg) {
28380         return getOrCreateCompilerPackageStats(pkg.getPackageName());
28381     }
28382 
28383     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
28384         return mCompilerStats.getOrCreatePackageStats(pkgName);
28385     }
28386 
28387     public void deleteCompilerPackageStats(String pkgName) {
28388         mCompilerStats.deletePackageStats(pkgName);
28389     }
28390 
28391     @Override
28392     public boolean isAutoRevokeWhitelisted(String packageName) {
28393         int mode = mInjector.getSystemService(AppOpsManager.class).checkOpNoThrow(
28394                 AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
28395                 Binder.getCallingUid(), packageName);
28396         return mode == MODE_IGNORED;
28397     }
28398 
28399     @Override
28400     public int getInstallReason(String packageName, int userId) {
28401         final int callingUid = Binder.getCallingUid();
28402         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
28403                 false /* checkShell */, "get install reason");
28404         synchronized (mLock) {
28405             final PackageSetting ps = mSettings.getPackageLPr(packageName);
28406             if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
28407                 return PackageManager.INSTALL_REASON_UNKNOWN;
28408             }
28409             if (ps != null) {
28410                 return ps.getInstallReason(userId);
28411             }
28412         }
28413         return PackageManager.INSTALL_REASON_UNKNOWN;
28414     }
28415 
28416     @Override
28417     public boolean canRequestPackageInstalls(String packageName, int userId) {
28418         return canRequestPackageInstallsInternal(packageName, Binder.getCallingUid(), userId,
28419                 true /* throwIfPermNotDeclared*/);
28420     }
28421 
28422     private boolean canRequestPackageInstallsInternal(String packageName, int callingUid,
28423             int userId, boolean throwIfPermNotDeclared) {
28424         int uid = getPackageUidInternal(packageName, 0, userId, callingUid);
28425         if (callingUid != uid && callingUid != Process.ROOT_UID
28426                 && callingUid != Process.SYSTEM_UID) {
28427             throw new SecurityException(
28428                     "Caller uid " + callingUid + " does not own package " + packageName);
28429         }
28430         if (isInstantAppInternal(packageName, userId, callingUid)) {
28431             return false;
28432         }
28433         final AndroidPackage pkg;
28434         synchronized (mLock) {
28435             pkg = mPackages.get(packageName);
28436         }
28437         if (pkg == null) {
28438             return false;
28439         }
28440         if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
28441             return false;
28442         }
28443         if (!pkg.getRequestedPermissions().contains(
28444                 android.Manifest.permission.REQUEST_INSTALL_PACKAGES)) {
28445             final String message = "Need to declare "
28446                     + android.Manifest.permission.REQUEST_INSTALL_PACKAGES
28447                     + " to call this api";
28448             if (throwIfPermNotDeclared) {
28449                 throw new SecurityException(message);
28450             } else {
28451                 Slog.e(TAG, message);
28452                 return false;
28453             }
28454         }
28455 
28456         return !isInstallDisabledForPackage(packageName, uid, userId);
28457     }
28458 
28459     /**
28460      * Returns true if the system or user is explicitly preventing an otherwise valid installer to
28461      * complete an install. This includes checks like unknown sources and user restrictions.
28462      */
28463     public boolean isInstallDisabledForPackage(String packageName, int uid, int userId) {
28464         if (mUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)
28465                 || mUserManager.hasUserRestriction(
28466                 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, userId)) {
28467             return true;
28468         }
28469         if (mExternalSourcesPolicy != null) {
28470             int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
28471             return isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
28472         }
28473         return false;
28474     }
28475 
28476     @Override
28477     public ComponentName getInstantAppResolverSettingsComponent() {
28478         return mInstantAppResolverSettingsComponent;
28479     }
28480 
28481     @Override
28482     public ComponentName getInstantAppInstallerComponent() {
28483         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
28484             return null;
28485         }
28486         return mInstantAppInstallerActivity == null
28487                 ? null : mInstantAppInstallerActivity.getComponentName();
28488     }
28489 
28490     @Override
28491     public String getInstantAppAndroidId(String packageName, int userId) {
28492         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
28493                 "getInstantAppAndroidId");
28494         enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
28495                 false /* checkShell */, "getInstantAppAndroidId");
28496         // Make sure the target is an Instant App.
28497         if (!isInstantApp(packageName, userId)) {
28498             return null;
28499         }
28500         synchronized (mLock) {
28501             return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
28502         }
28503     }
28504 
28505     @Override
28506     public void grantImplicitAccess(int recipientUid, String visibleAuthority) {
28507         // This API is exposed temporarily to only the contacts provider. (b/158688602)
28508         final int callingUid = Binder.getCallingUid();
28509         ProviderInfo contactsProvider = resolveContentProviderInternal(
28510                         ContactsContract.AUTHORITY, 0, UserHandle.getUserId(callingUid));
28511         if (contactsProvider == null || contactsProvider.applicationInfo == null
28512                 || !UserHandle.isSameApp(contactsProvider.applicationInfo.uid, callingUid)) {
28513             throw new SecurityException(callingUid + " is not allow to call grantImplicitAccess");
28514         }
28515         final int userId = UserHandle.getUserId(recipientUid);
28516         final long token = Binder.clearCallingIdentity();
28517         final ProviderInfo providerInfo;
28518         try {
28519             providerInfo = resolveContentProvider(visibleAuthority, 0 /*flags*/, userId);
28520         } finally {
28521             Binder.restoreCallingIdentity(token);
28522         }
28523         if (providerInfo == null) {
28524             return;
28525         }
28526         int visibleUid = providerInfo.applicationInfo.uid;
28527         mPmInternal.grantImplicitAccess(userId, null /*Intent*/, UserHandle.getAppId(recipientUid),
28528                 visibleUid, false);
28529     }
28530 
28531     boolean canHaveOatDir(String packageName) {
28532         synchronized (mLock) {
28533             AndroidPackage p = mPackages.get(packageName);
28534             PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
28535             if (p == null || pkgSetting == null) {
28536                 return false;
28537             }
28538             return AndroidPackageUtils.canHaveOatDir(p,
28539                     pkgSetting.getPkgState().isUpdatedSystemApp());
28540         }
28541     }
28542 
28543     long deleteOatArtifactsOfPackage(String packageName) {
28544         final AndroidPackage pkg;
28545         final PackageSetting pkgSetting;
28546         synchronized (mLock) {
28547             pkg = mPackages.get(packageName);
28548             pkgSetting = mSettings.getPackageLPr(packageName);
28549         }
28550         return mDexManager.deleteOptimizedFiles(ArtUtils.createArtPackageInfo(pkg, pkgSetting));
28551     }
28552 
28553     Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
28554         Set<String> unusedPackages = new HashSet<>();
28555         long currentTimeInMillis = System.currentTimeMillis();
28556         synchronized (mLock) {
28557             for (AndroidPackage pkg : mPackages.values()) {
28558                 PackageSetting ps =  mSettings.getPackageLPr(pkg.getPackageName());
28559                 if (ps == null) {
28560                     continue;
28561                 }
28562                 PackageDexUsage.PackageUseInfo packageUseInfo =
28563                       getDexManager().getPackageUseInfoOrDefault(pkg.getPackageName());
28564                 if (PackageManagerServiceUtils
28565                         .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
28566                                 downgradeTimeThresholdMillis, packageUseInfo,
28567                                 ps.getPkgState().getLatestPackageUseTimeInMills(),
28568                                 ps.getPkgState().getLatestForegroundPackageUseTimeInMills())) {
28569                     unusedPackages.add(pkg.getPackageName());
28570                 }
28571             }
28572         }
28573         return unusedPackages;
28574     }
28575 
28576     @Override
28577     public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
28578             int userId) {
28579         final int callingUid = Binder.getCallingUid();
28580         final int callingAppId = UserHandle.getAppId(callingUid);
28581 
28582         enforceCrossUserPermission(callingUid, userId, true /*requireFullPermission*/,
28583                 true /*checkShell*/, "setHarmfulAppInfo");
28584 
28585         if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
28586                 checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
28587             throw new SecurityException("Caller must have the "
28588                     + SET_HARMFUL_APP_WARNINGS + " permission.");
28589         }
28590 
28591         synchronized (mLock) {
28592             mSettings.setHarmfulAppWarningLPw(packageName, warning, userId);
28593             scheduleWritePackageRestrictionsLocked(userId);
28594         }
28595     }
28596 
28597     @Nullable
28598     @Override
28599     public CharSequence getHarmfulAppWarning(@NonNull String packageName, int userId) {
28600         final int callingUid = Binder.getCallingUid();
28601         final int callingAppId = UserHandle.getAppId(callingUid);
28602 
28603         enforceCrossUserPermission(callingUid, userId, true /*requireFullPermission*/,
28604                 true /*checkShell*/, "getHarmfulAppInfo");
28605 
28606         if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
28607                 checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
28608             throw new SecurityException("Caller must have the "
28609                     + SET_HARMFUL_APP_WARNINGS + " permission.");
28610         }
28611 
28612         synchronized (mLock) {
28613             return mSettings.getHarmfulAppWarningLPr(packageName, userId);
28614         }
28615     }
28616 
28617     @Override
28618     public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) {
28619         final int callingUid = Binder.getCallingUid();
28620         final int callingAppId = UserHandle.getAppId(callingUid);
28621 
28622         enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
28623                 true /*checkShell*/, "isPackageStateProtected");
28624 
28625         if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID
28626                 && checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid) != PERMISSION_GRANTED) {
28627             throw new SecurityException("Caller must have the "
28628                     + MANAGE_DEVICE_ADMINS + " permission.");
28629         }
28630 
28631         return mProtectedPackages.isPackageStateProtected(userId, packageName);
28632     }
28633 
28634     @Override
28635     public void sendDeviceCustomizationReadyBroadcast() {
28636         mContext.enforceCallingPermission(Manifest.permission.SEND_DEVICE_CUSTOMIZATION_READY,
28637                 "sendDeviceCustomizationReadyBroadcast");
28638 
28639         final long ident = Binder.clearCallingIdentity();
28640         try {
28641             final Intent intent = new Intent(Intent.ACTION_DEVICE_CUSTOMIZATION_READY);
28642             intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
28643             final IActivityManager am = ActivityManager.getService();
28644             final String[] requiredPermissions = {
28645                 Manifest.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY,
28646             };
28647             try {
28648                 am.broadcastIntentWithFeature(null, null, intent, null, null, 0, null, null,
28649                         requiredPermissions, null, android.app.AppOpsManager.OP_NONE, null, false,
28650                         false, UserHandle.USER_ALL);
28651             } catch (RemoteException e) {
28652                 throw e.rethrowFromSystemServer();
28653             }
28654         } finally {
28655             Binder.restoreCallingIdentity(ident);
28656         }
28657     }
28658 
28659     private void applyMimeGroupChanges(String packageName, String mimeGroup) {
28660         if (mComponentResolver.updateMimeGroup(packageName, mimeGroup)) {
28661             Binder.withCleanCallingIdentity(() ->
28662                     clearPackagePreferredActivities(packageName, UserHandle.USER_ALL));
28663         }
28664 
28665         mPmInternal.writeSettings(false);
28666     }
28667 
28668     @Override
28669     public void setMimeGroup(String packageName, String mimeGroup, List<String> mimeTypes) {
28670         enforceOwnerRights(packageName, Binder.getCallingUid());
28671         final boolean changed;
28672         synchronized (mLock) {
28673             changed = mSettings.getPackageLPr(packageName).setMimeGroup(mimeGroup, mimeTypes);
28674         }
28675         if (changed) {
28676             applyMimeGroupChanges(packageName, mimeGroup);
28677         }
28678     }
28679 
28680     @Override
28681     public List<String> getMimeGroup(String packageName, String mimeGroup) {
28682         enforceOwnerRights(packageName, Binder.getCallingUid());
28683         return getMimeGroupInternal(packageName, mimeGroup);
28684     }
28685 
28686     private List<String> getMimeGroupInternal(String packageName, String mimeGroup) {
28687         synchronized (mLock) {
28688             return mSettings.getPackageLPr(packageName).getMimeGroup(mimeGroup);
28689         }
28690     }
28691 
28692     @Override
28693     public void setSplashScreenTheme(@NonNull String packageName, @Nullable String themeId,
28694             int userId) {
28695         int callingUid = Binder.getCallingUid();
28696         PackageSetting packageSetting = getPackageSettingForUser(packageName, callingUid, userId);
28697         if (packageSetting != null) {
28698             packageSetting.setSplashScreenTheme(userId, themeId);
28699         }
28700     }
28701 
28702     @Override
28703     public String getSplashScreenTheme(@NonNull String packageName, int userId) {
28704         int callingUid = Binder.getCallingUid();
28705         PackageSetting packageSetting = getPackageSettingForUser(packageName, callingUid, userId);
28706         return packageSetting != null ? packageSetting.getSplashScreenTheme(userId) : null;
28707     }
28708 
28709     /**
28710      * Temporary method that wraps mSettings.writeLPr() and calls mPermissionManager's
28711      * writeLegacyPermissionsTEMP() beforehand.
28712      *
28713      * TODO(zhanghai): This should be removed once we finish migration of permission storage.
28714      */
28715     private void writeSettingsLPrTEMP() {
28716         mPermissionManager.writeLegacyPermissionsTEMP(mSettings.mPermissions);
28717         mSettings.writeLPr();
28718     }
28719 
28720     @Override
28721     public IBinder getHoldLockToken() {
28722         if (!Build.IS_DEBUGGABLE) {
28723             throw new SecurityException("getHoldLockToken requires a debuggable build");
28724         }
28725 
28726         mContext.enforceCallingPermission(
28727                 Manifest.permission.INJECT_EVENTS,
28728                 "getHoldLockToken requires INJECT_EVENTS permission");
28729 
28730         final Binder token = new Binder();
28731         token.attachInterface(this, "holdLock:" + Binder.getCallingUid());
28732         return token;
28733     }
28734 
28735     @Override
28736     public void verifyHoldLockToken(IBinder token) {
28737         if (!Build.IS_DEBUGGABLE) {
28738             throw new SecurityException("holdLock requires a debuggable build");
28739         }
28740 
28741         if (token == null) {
28742             throw new SecurityException("null holdLockToken");
28743         }
28744 
28745         if (token.queryLocalInterface("holdLock:" + Binder.getCallingUid()) != this) {
28746             throw new SecurityException("Invalid holdLock() token");
28747         }
28748     }
28749 
28750     @Override
28751     public void holdLock(IBinder token, int durationMs) {
28752         mTestUtilityService.verifyHoldLockToken(token);
28753 
28754         synchronized (mLock) {
28755             SystemClock.sleep(durationMs);
28756         }
28757     }
28758 
28759     private static String getDefaultTimeouts() {
28760         final long token = Binder.clearCallingIdentity();
28761         try {
28762             return DeviceConfig.getString(NAMESPACE_PACKAGE_MANAGER_SERVICE,
28763                     PROPERTY_INCFS_DEFAULT_TIMEOUTS, "");
28764         } finally {
28765             Binder.restoreCallingIdentity(token);
28766         }
28767     }
28768 
28769     private static String getKnownDigestersList() {
28770         final long token = Binder.clearCallingIdentity();
28771         try {
28772             return DeviceConfig.getString(NAMESPACE_PACKAGE_MANAGER_SERVICE,
28773                     PROPERTY_KNOWN_DIGESTERS_LIST, "");
28774         } finally {
28775             Binder.restoreCallingIdentity(token);
28776         }
28777     }
28778 
28779     /**
28780      * Returns the array containing per-uid timeout configuration.
28781      * This is derived from DeviceConfig flags.
28782      */
28783     public @NonNull PerUidReadTimeouts[] getPerUidReadTimeouts() {
28784         PerUidReadTimeouts[] result = mPerUidReadTimeoutsCache;
28785         if (result == null) {
28786             result = parsePerUidReadTimeouts();
28787             mPerUidReadTimeoutsCache = result;
28788         }
28789         return result;
28790     }
28791 
28792     private @NonNull PerUidReadTimeouts[] parsePerUidReadTimeouts() {
28793         final String defaultTimeouts = getDefaultTimeouts();
28794         final String knownDigestersList = getKnownDigestersList();
28795         final List<PerPackageReadTimeouts> perPackageReadTimeouts =
28796                 PerPackageReadTimeouts.parseDigestersList(defaultTimeouts, knownDigestersList);
28797 
28798         if (perPackageReadTimeouts.size() == 0) {
28799             return EMPTY_PER_UID_READ_TIMEOUTS_ARRAY;
28800         }
28801 
28802         final int[] allUsers = mInjector.getUserManagerService().getUserIds();
28803 
28804         List<PerUidReadTimeouts> result = new ArrayList<>(perPackageReadTimeouts.size());
28805         synchronized (mLock) {
28806             for (int i = 0, size = perPackageReadTimeouts.size(); i < size; ++i) {
28807                 final PerPackageReadTimeouts perPackage = perPackageReadTimeouts.get(i);
28808                 final PackageSetting ps = mSettings.mPackages.get(perPackage.packageName);
28809                 if (ps == null) {
28810                     if (DEBUG_PER_UID_READ_TIMEOUTS) {
28811                         Slog.i(TAG, "PerUidReadTimeouts: package not found = "
28812                                 + perPackage.packageName);
28813                     }
28814                     continue;
28815                 }
28816                 if (ps.appId < Process.FIRST_APPLICATION_UID) {
28817                     if (DEBUG_PER_UID_READ_TIMEOUTS) {
28818                         Slog.i(TAG, "PerUidReadTimeouts: package is system, appId=" + ps.appId);
28819                     }
28820                     continue;
28821                 }
28822 
28823                 final AndroidPackage pkg = ps.getPkg();
28824                 if (pkg.getLongVersionCode() < perPackage.versionCodes.minVersionCode
28825                         || pkg.getLongVersionCode() > perPackage.versionCodes.maxVersionCode) {
28826                     if (DEBUG_PER_UID_READ_TIMEOUTS) {
28827                         Slog.i(TAG, "PerUidReadTimeouts: version code is not in range = "
28828                                 + perPackage.packageName + ":" + pkg.getLongVersionCode());
28829                     }
28830                     continue;
28831                 }
28832                 if (perPackage.sha256certificate != null
28833                         && !pkg.getSigningDetails().hasSha256Certificate(
28834                         perPackage.sha256certificate)) {
28835                     if (DEBUG_PER_UID_READ_TIMEOUTS) {
28836                         Slog.i(TAG, "PerUidReadTimeouts: invalid certificate = "
28837                                 + perPackage.packageName + ":" + pkg.getLongVersionCode());
28838                     }
28839                     continue;
28840                 }
28841                 for (int userId : allUsers) {
28842                     if (!ps.getInstalled(userId)) {
28843                         continue;
28844                     }
28845                     final int uid = UserHandle.getUid(userId, ps.appId);
28846                     final PerUidReadTimeouts perUid = new PerUidReadTimeouts();
28847                     perUid.uid = uid;
28848                     perUid.minTimeUs = perPackage.timeouts.minTimeUs;
28849                     perUid.minPendingTimeUs = perPackage.timeouts.minPendingTimeUs;
28850                     perUid.maxPendingTimeUs = perPackage.timeouts.maxPendingTimeUs;
28851                     result.add(perUid);
28852                 }
28853             }
28854         }
28855         return result.toArray(new PerUidReadTimeouts[result.size()]);
28856     }
28857 
28858     static @NonNull BroadcastOptions getTemporaryAppAllowlistBroadcastOptions(
28859             @PowerWhitelistManager.ReasonCode int reasonCode) {
28860         long duration = 10_000;
28861         final ActivityManagerInternal amInternal =
28862                 LocalServices.getService(ActivityManagerInternal.class);
28863         if (amInternal != null) {
28864             duration = amInternal.getBootTimeTempAllowListDuration();
28865         }
28866         final BroadcastOptions bOptions = BroadcastOptions.makeBasic();
28867         bOptions.setTemporaryAppAllowlist(duration,
28868                 TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
28869                 reasonCode, "");
28870         return bOptions;
28871     }
28872 
28873     @NonNull
28874     public DomainVerificationService.Connection getDomainVerificationConnection() {
28875         return mDomainVerificationConnection;
28876     }
28877 
28878     @Override
28879     public void setKeepUninstalledPackages(List<String> packageList) {
28880         mContext.enforceCallingPermission(
28881                 Manifest.permission.KEEP_UNINSTALLED_PACKAGES,
28882                 "setKeepUninstalledPackages requires KEEP_UNINSTALLED_PACKAGES permission");
28883         Objects.requireNonNull(packageList);
28884 
28885         setKeepUninstalledPackagesInternal(packageList);
28886     }
28887 
28888     private void setKeepUninstalledPackagesInternal(List<String> packageList) {
28889         Preconditions.checkNotNull(packageList);
28890         List<String> removedFromList = null;
28891         synchronized (mLock) {
28892             if (mKeepUninstalledPackages != null) {
28893                 final int packagesCount = mKeepUninstalledPackages.size();
28894                 for (int i = 0; i < packagesCount; i++) {
28895                     String oldPackage = mKeepUninstalledPackages.get(i);
28896                     if (packageList != null && packageList.contains(oldPackage)) {
28897                         continue;
28898                     }
28899                     if (removedFromList == null) {
28900                         removedFromList = new ArrayList<>();
28901                     }
28902                     removedFromList.add(oldPackage);
28903                 }
28904             }
28905             mKeepUninstalledPackages = new ArrayList<>(packageList);
28906             if (removedFromList != null) {
28907                 final int removedCount = removedFromList.size();
28908                 for (int i = 0; i < removedCount; i++) {
28909                     deletePackageIfUnusedLPr(removedFromList.get(i));
28910                 }
28911             }
28912         }
28913     }
28914 
28915     private static class TempUserState {
28916         public final int enabledState;
28917         @Nullable
28918         public final String lastDisableAppCaller;
28919         public final boolean installed;
28920 
28921         private TempUserState(int enabledState, @Nullable String lastDisableAppCaller,
28922                 boolean installed) {
28923             this.enabledState = enabledState;
28924             this.lastDisableAppCaller = lastDisableAppCaller;
28925             this.installed = installed;
28926         }
28927     }
28928 }
28929 
28930 interface PackageSender {
28931     /**
28932      * @param userIds User IDs where the action occurred on a full application
28933      * @param instantUserIds User IDs where the action occurred on an instant application
28934      */
28935     void sendPackageBroadcast(final String action, final String pkg,
28936             final Bundle extras, final int flags, final String targetPkg,
28937             final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds,
28938             @Nullable SparseArray<int[]> broadcastAllowList, @Nullable Bundle bOptions);
28939     void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
28940             boolean includeStopped, int appId, int[] userIds, int[] instantUserIds,
28941             int dataLoaderType);
28942     void notifyPackageAdded(String packageName, int uid);
28943     void notifyPackageChanged(String packageName, int uid);
28944     void notifyPackageRemoved(String packageName, int uid);
28945 }
28946