2 * Copyright (C) 2006 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.server.pm;
19 import static android.Manifest.permission.DELETE_PACKAGES;
20 import static android.Manifest.permission.INSTALL_PACKAGES;
21 import static android.Manifest.permission.MANAGE_DEVICE_ADMINS;
22 import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
23 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
24 import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
25 import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS;
26 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
27 import static android.content.Intent.ACTION_MAIN;
28 import static android.content.Intent.CATEGORY_DEFAULT;
29 import static android.content.Intent.CATEGORY_HOME;
30 import static android.content.Intent.EXTRA_LONG_VERSION_CODE;
31 import static android.content.Intent.EXTRA_PACKAGE_NAME;
32 import static android.content.Intent.EXTRA_VERSION_CODE;
33 import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509;
34 import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
35 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
36 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
37 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
38 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
39 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
40 import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ID;
41 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
42 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
43 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
44 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
45 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
46 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
47 import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER;
48 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
49 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
50 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
51 import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
52 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
53 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
54 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
55 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
56 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
57 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
58 import static android.content.pm.PackageManager.INSTALL_FAILED_PROCESS_NOT_DEFINED;
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_SUCCEEDED;
67 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
68 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
69 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
70 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
71 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
72 import static android.content.pm.PackageManager.MATCH_ALL;
73 import static android.content.pm.PackageManager.MATCH_ANY_USER;
74 import static android.content.pm.PackageManager.MATCH_APEX;
75 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
76 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
77 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
78 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
79 import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
80 import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
81 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
82 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
83 import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
84 import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
85 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
86 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
87 import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
88 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
89 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
90 import static android.content.pm.PackageManager.PERMISSION_DENIED;
91 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
92 import static android.content.pm.PackageManager.RESTRICTION_NONE;
93 import static android.content.pm.PackageParser.isApkFile;
94 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
95 import static android.os.incremental.IncrementalManager.isIncrementalPath;
96 import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
97 import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
98 import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
99 import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
101 import static com.android.internal.annotations.VisibleForTesting.Visibility;
102 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
103 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
104 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
105 import static com.android.internal.util.ArrayUtils.emptyIfNull;
106 import static com.android.internal.util.ArrayUtils.filter;
107 import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME;
108 import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_INIT_TIME;
109 import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME;
110 import static com.android.server.pm.ComponentResolver.RESOLVE_PRIORITY_SORTER;
111 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
112 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
113 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
114 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
115 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
116 import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
117 import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
118 import static com.android.server.pm.PackageManagerServiceUtils.decompressFile;
119 import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
120 import static com.android.server.pm.PackageManagerServiceUtils.dumpCriticalInfo;
121 import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFiles;
122 import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
123 import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
124 import static com.android.server.pm.PackageManagerServiceUtils.makeDirRecursive;
125 import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
127 import android.Manifest;
128 import android.annotation.AppIdInt;
129 import android.annotation.IntDef;
130 import android.annotation.NonNull;
131 import android.annotation.Nullable;
132 import android.annotation.UserIdInt;
133 import android.annotation.WorkerThread;
134 import android.app.ActivityManager;
135 import android.app.AppOpsManager;
136 import android.app.ApplicationPackageManager;
137 import android.app.BroadcastOptions;
138 import android.app.IActivityManager;
139 import android.app.ResourcesManager;
140 import android.app.admin.IDevicePolicyManager;
141 import android.app.admin.SecurityLog;
142 import android.app.backup.IBackupManager;
143 import android.content.BroadcastReceiver;
144 import android.content.ComponentName;
145 import android.content.ContentResolver;
146 import android.content.Context;
147 import android.content.IIntentReceiver;
148 import android.content.Intent;
149 import android.content.IntentFilter;
150 import android.content.IntentSender;
151 import android.content.IntentSender.SendIntentException;
152 import android.content.pm.ActivityInfo;
153 import android.content.pm.ApplicationInfo;
154 import android.content.pm.AuxiliaryResolveInfo;
155 import android.content.pm.ChangedPackages;
156 import android.content.pm.ComponentInfo;
157 import android.content.pm.DataLoaderType;
158 import android.content.pm.FallbackCategoryProvider;
159 import android.content.pm.FeatureInfo;
160 import android.content.pm.IDexModuleRegisterCallback;
161 import android.content.pm.IPackageDataObserver;
162 import android.content.pm.IPackageDeleteObserver;
163 import android.content.pm.IPackageDeleteObserver2;
164 import android.content.pm.IPackageInstallObserver2;
165 import android.content.pm.IPackageInstaller;
166 import android.content.pm.IPackageManager;
167 import android.content.pm.IPackageManagerNative;
168 import android.content.pm.IPackageMoveObserver;
169 import android.content.pm.IPackageStatsObserver;
170 import android.content.pm.InstallSourceInfo;
171 import android.content.pm.InstantAppInfo;
172 import android.content.pm.InstantAppRequest;
173 import android.content.pm.InstantAppResolveInfo.InstantAppDigest;
174 import android.content.pm.InstrumentationInfo;
175 import android.content.pm.IntentFilterVerificationInfo;
176 import android.content.pm.KeySet;
177 import android.content.pm.ModuleInfo;
178 import android.content.pm.PackageInfo;
179 import android.content.pm.PackageInfoLite;
180 import android.content.pm.PackageInstaller;
181 import android.content.pm.PackageManager;
182 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
183 import android.content.pm.PackageManager.ModuleInfoFlags;
184 import android.content.pm.PackageManagerInternal;
185 import android.content.pm.PackageManagerInternal.PackageListObserver;
186 import android.content.pm.PackageManagerInternal.PrivateResolveFlags;
187 import android.content.pm.PackageParser;
188 import android.content.pm.PackageParser.PackageLite;
189 import android.content.pm.PackageParser.PackageParserException;
190 import android.content.pm.PackageParser.ParseFlags;
191 import android.content.pm.PackageParser.SigningDetails;
192 import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
193 import android.content.pm.PackagePartitions;
194 import android.content.pm.PackagePartitions.SystemPartition;
195 import android.content.pm.PackageStats;
196 import android.content.pm.PackageUserState;
197 import android.content.pm.ParceledListSlice;
198 import android.content.pm.PermissionGroupInfo;
199 import android.content.pm.PermissionInfo;
200 import android.content.pm.ProcessInfo;
201 import android.content.pm.ProviderInfo;
202 import android.content.pm.ResolveInfo;
203 import android.content.pm.SELinuxUtil;
204 import android.content.pm.ServiceInfo;
205 import android.content.pm.SharedLibraryInfo;
206 import android.content.pm.Signature;
207 import android.content.pm.SigningInfo;
208 import android.content.pm.SuspendDialogInfo;
209 import android.content.pm.UserInfo;
210 import android.content.pm.VerifierDeviceIdentity;
211 import android.content.pm.VerifierInfo;
212 import android.content.pm.VersionedPackage;
213 import android.content.pm.dex.ArtManager;
214 import android.content.pm.dex.DexMetadataHelper;
215 import android.content.pm.dex.IArtManager;
216 import android.content.pm.parsing.PackageInfoWithoutStateUtils;
217 import android.content.pm.parsing.ParsingPackageUtils;
218 import android.content.pm.parsing.component.ParsedActivity;
219 import android.content.pm.parsing.component.ParsedInstrumentation;
220 import android.content.pm.parsing.component.ParsedIntentInfo;
221 import android.content.pm.parsing.component.ParsedMainComponent;
222 import android.content.pm.parsing.component.ParsedPermission;
223 import android.content.pm.parsing.component.ParsedProcess;
224 import android.content.pm.parsing.component.ParsedProvider;
225 import android.content.pm.parsing.component.ParsedService;
226 import android.content.res.Resources;
227 import android.content.rollback.IRollbackManager;
228 import android.database.ContentObserver;
229 import android.graphics.Bitmap;
230 import android.hardware.display.DisplayManager;
231 import android.net.Uri;
232 import android.os.AsyncTask;
233 import android.os.Binder;
234 import android.os.Build;
235 import android.os.Bundle;
236 import android.os.Debug;
237 import android.os.Environment;
238 import android.os.FileUtils;
239 import android.os.Handler;
240 import android.os.IBinder;
241 import android.os.Looper;
242 import android.os.Message;
243 import android.os.Parcel;
244 import android.os.PatternMatcher;
245 import android.os.PersistableBundle;
246 import android.os.Process;
247 import android.os.RemoteCallbackList;
248 import android.os.RemoteException;
249 import android.os.ResultReceiver;
250 import android.os.SELinux;
251 import android.os.ServiceManager;
252 import android.os.ShellCallback;
253 import android.os.SystemClock;
254 import android.os.SystemProperties;
255 import android.os.Trace;
256 import android.os.UserHandle;
257 import android.os.UserManager;
258 import android.os.UserManagerInternal;
259 import android.os.incremental.IncrementalManager;
260 import android.os.storage.DiskInfo;
261 import android.os.storage.IStorageManager;
262 import android.os.storage.StorageEventListener;
263 import android.os.storage.StorageManager;
264 import android.os.storage.StorageManagerInternal;
265 import android.os.storage.VolumeInfo;
266 import android.os.storage.VolumeRecord;
267 import android.permission.IPermissionManager;
268 import android.provider.DeviceConfig;
269 import android.provider.Settings.Global;
270 import android.provider.Settings.Secure;
271 import android.security.KeyStore;
272 import android.security.SystemKeyStore;
273 import android.service.pm.PackageServiceDumpProto;
274 import android.stats.storage.StorageEnums;
275 import android.system.ErrnoException;
276 import android.system.Os;
277 import android.text.TextUtils;
278 import android.text.format.DateUtils;
279 import android.util.ArrayMap;
280 import android.util.ArraySet;
281 import android.util.Base64;
282 import android.util.DisplayMetrics;
283 import android.util.EventLog;
284 import android.util.ExceptionUtils;
285 import android.util.IntArray;
286 import android.util.Log;
287 import android.util.LogPrinter;
288 import android.util.LongSparseArray;
289 import android.util.LongSparseLongArray;
290 import android.util.MathUtils;
291 import android.util.PackageUtils;
292 import android.util.Pair;
293 import android.util.PrintStreamPrinter;
294 import android.util.Slog;
295 import android.util.SparseArray;
296 import android.util.SparseBooleanArray;
297 import android.util.SparseIntArray;
298 import android.util.TimingsTraceLog;
299 import android.util.Xml;
300 import android.util.apk.ApkSignatureVerifier;
301 import android.util.jar.StrictJarFile;
302 import android.util.proto.ProtoOutputStream;
303 import android.view.Display;
305 import com.android.internal.R;
306 import com.android.internal.annotations.GuardedBy;
307 import com.android.internal.annotations.VisibleForTesting;
308 import com.android.internal.app.ResolverActivity;
309 import com.android.internal.content.NativeLibraryHelper;
310 import com.android.internal.content.PackageHelper;
311 import com.android.internal.content.om.OverlayConfig;
312 import com.android.internal.logging.MetricsLogger;
313 import com.android.internal.os.SomeArgs;
314 import com.android.internal.os.Zygote;
315 import com.android.internal.telephony.CarrierAppUtils;
316 import com.android.internal.util.ArrayUtils;
317 import com.android.internal.util.ConcurrentUtils;
318 import com.android.internal.util.DumpUtils;
319 import com.android.internal.util.FastXmlSerializer;
320 import com.android.internal.util.FrameworkStatsLog;
321 import com.android.internal.util.IndentingPrintWriter;
322 import com.android.internal.util.Preconditions;
323 import com.android.server.AttributeCache;
324 import com.android.server.DeviceIdleInternal;
325 import com.android.server.EventLogTags;
326 import com.android.server.FgThread;
327 import com.android.server.LocalServices;
328 import com.android.server.LockGuard;
329 import com.android.server.PackageWatchdog;
330 import com.android.server.ServiceThread;
331 import com.android.server.SystemConfig;
332 import com.android.server.SystemServerInitThreadPool;
333 import com.android.server.Watchdog;
334 import com.android.server.compat.PlatformCompat;
335 import com.android.server.net.NetworkPolicyManagerInternal;
336 import com.android.server.pm.Installer.InstallerException;
337 import com.android.server.pm.Settings.DatabaseVersion;
338 import com.android.server.pm.Settings.VersionInfo;
339 import com.android.server.pm.dex.ArtManagerService;
340 import com.android.server.pm.dex.DexManager;
341 import com.android.server.pm.dex.DexoptOptions;
342 import com.android.server.pm.dex.PackageDexUsage;
343 import com.android.server.pm.dex.ViewCompiler;
344 import com.android.server.pm.parsing.PackageInfoUtils;
345 import com.android.server.pm.parsing.PackageParser2;
346 import com.android.server.pm.parsing.library.PackageBackwardCompatibility;
347 import com.android.server.pm.parsing.pkg.AndroidPackage;
348 import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
349 import com.android.server.pm.parsing.pkg.PackageImpl;
350 import com.android.server.pm.parsing.pkg.ParsedPackage;
351 import com.android.server.pm.permission.BasePermission;
352 import com.android.server.pm.permission.PermissionManagerService;
353 import com.android.server.pm.permission.PermissionManagerServiceInternal;
354 import com.android.server.pm.permission.PermissionsState;
355 import com.android.server.policy.PermissionPolicyInternal;
356 import com.android.server.security.VerityUtils;
357 import com.android.server.storage.DeviceStorageMonitorInternal;
358 import com.android.server.utils.TimingsTraceAndSlog;
359 import com.android.server.wm.ActivityTaskManagerInternal;
361 import dalvik.system.CloseGuard;
362 import dalvik.system.VMRuntime;
364 import libcore.io.IoUtils;
365 import libcore.util.EmptyArray;
366 import libcore.util.HexEncoding;
368 import org.xmlpull.v1.XmlPullParser;
369 import org.xmlpull.v1.XmlPullParserException;
370 import org.xmlpull.v1.XmlSerializer;
372 import java.io.BufferedOutputStream;
373 import java.io.ByteArrayInputStream;
374 import java.io.ByteArrayOutputStream;
376 import java.io.FileDescriptor;
377 import java.io.FileInputStream;
378 import java.io.FileOutputStream;
379 import java.io.IOException;
380 import java.io.PrintWriter;
381 import java.lang.annotation.Retention;
382 import java.lang.annotation.RetentionPolicy;
383 import java.nio.charset.StandardCharsets;
384 import java.security.DigestException;
385 import java.security.DigestInputStream;
386 import java.security.MessageDigest;
387 import java.security.NoSuchAlgorithmException;
388 import java.security.PublicKey;
389 import java.security.SecureRandom;
390 import java.security.cert.CertificateException;
391 import java.util.ArrayList;
392 import java.util.Arrays;
393 import java.util.Collection;
394 import java.util.Collections;
395 import java.util.Comparator;
396 import java.util.HashMap;
397 import java.util.HashSet;
398 import java.util.Iterator;
399 import java.util.LinkedHashSet;
400 import java.util.List;
401 import java.util.Map;
402 import java.util.Objects;
403 import java.util.Set;
404 import java.util.UUID;
405 import java.util.concurrent.CountDownLatch;
406 import java.util.concurrent.ExecutorService;
407 import java.util.concurrent.Future;
408 import java.util.concurrent.TimeUnit;
409 import java.util.concurrent.atomic.AtomicBoolean;
410 import java.util.concurrent.atomic.AtomicInteger;
411 import java.util.function.BiConsumer;
412 import java.util.function.Consumer;
413 import java.util.function.Predicate;
414 import java.util.stream.Collectors;
417 * Keep track of all those APKs everywhere.
419 * Internally there are two important locks:
421 * <li>{@link #mLock} is used to guard all in-memory parsed package details
422 * and other related state. It is a fine-grained lock that should only be held
423 * momentarily, as it's one of the most contended locks in the system.
424 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
425 * operations typically involve heavy lifting of application data on disk. Since
426 * {@code installd} is single-threaded, and it's operations can often be slow,
427 * this lock should never be acquired while already holding {@link #mLock}.
428 * Conversely, it's safe to acquire {@link #mLock} momentarily while already
429 * holding {@link #mInstallLock}.
431 * Many internal methods rely on the caller to hold the appropriate locks, and
432 * this contract is expressed through method name suffixes:
434 * <li>fooLI(): the caller must hold {@link #mInstallLock}
435 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
436 * being modified must be frozen
437 * <li>fooLPr(): the caller must hold {@link #mLock} for reading
438 * <li>fooLPw(): the caller must hold {@link #mLock} for writing
441 * Because this class is very central to the platform's security; please run all
442 * CTS and unit tests whenever making modifications:
445 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
446 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
449 public class PackageManagerService extends IPackageManager.Stub
450 implements PackageSender {
451 static final String TAG = "PackageManager";
452 public static final boolean DEBUG_SETTINGS = false;
453 static final boolean DEBUG_PREFERRED = false;
454 static final boolean DEBUG_UPGRADE = false;
455 static final boolean DEBUG_DOMAIN_VERIFICATION = false;
456 private static final boolean DEBUG_BACKUP = false;
457 public static final boolean DEBUG_INSTALL = false;
458 public static final boolean DEBUG_REMOVE = false;
459 private static final boolean DEBUG_BROADCASTS = false;
460 private static final boolean DEBUG_PACKAGE_INFO = false;
461 private static final boolean DEBUG_INTENT_MATCHING = false;
462 public static final boolean DEBUG_PACKAGE_SCANNING = false;
463 private static final boolean DEBUG_VERIFY = false;
464 public static final boolean DEBUG_PERMISSIONS = false;
465 private static final boolean DEBUG_SHARED_LIBRARIES = false;
466 public static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
468 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
469 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
470 // user, but by default initialize to this.
471 public static final boolean DEBUG_DEXOPT = false;
473 static final boolean DEBUG_ABI_SELECTION = false;
474 private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE;
475 private static final boolean DEBUG_APP_DATA = false;
477 /** REMOVE. According to Svet, this was only used to reset permissions during development. */
478 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
480 private static final boolean HIDE_EPHEMERAL_APIS = false;
482 private static final boolean ENABLE_FREE_CACHE_V2 =
483 SystemProperties.getBoolean("fw.free_cache_v2", true);
485 private static final String PRECOMPILE_LAYOUTS = "pm.precompile_layouts";
487 private static final int RADIO_UID = Process.PHONE_UID;
488 private static final int LOG_UID = Process.LOG_UID;
489 private static final int NFC_UID = Process.NFC_UID;
490 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
491 private static final int SHELL_UID = Process.SHELL_UID;
492 private static final int SE_UID = Process.SE_UID;
493 private static final int NETWORKSTACK_UID = Process.NETWORK_STACK_UID;
495 static final int SCAN_NO_DEX = 1 << 0;
496 static final int SCAN_UPDATE_SIGNATURE = 1 << 1;
497 static final int SCAN_NEW_INSTALL = 1 << 2;
498 static final int SCAN_UPDATE_TIME = 1 << 3;
499 static final int SCAN_BOOTING = 1 << 4;
500 static final int SCAN_REQUIRE_KNOWN = 1 << 7;
501 static final int SCAN_MOVE = 1 << 8;
502 static final int SCAN_INITIAL = 1 << 9;
503 static final int SCAN_DONT_KILL_APP = 1 << 10;
504 static final int SCAN_IGNORE_FROZEN = 1 << 11;
505 static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1 << 12;
506 static final int SCAN_AS_INSTANT_APP = 1 << 13;
507 static final int SCAN_AS_FULL_APP = 1 << 14;
508 static final int SCAN_AS_VIRTUAL_PRELOAD = 1 << 15;
509 static final int SCAN_AS_SYSTEM = 1 << 16;
510 static final int SCAN_AS_PRIVILEGED = 1 << 17;
511 static final int SCAN_AS_OEM = 1 << 18;
512 static final int SCAN_AS_VENDOR = 1 << 19;
513 static final int SCAN_AS_PRODUCT = 1 << 20;
514 static final int SCAN_AS_SYSTEM_EXT = 1 << 21;
515 static final int SCAN_AS_ODM = 1 << 22;
516 static final int SCAN_AS_APK_IN_APEX = 1 << 23;
518 @IntDef(flag = true, prefix = { "SCAN_" }, value = {
520 SCAN_UPDATE_SIGNATURE,
529 SCAN_FIRST_BOOT_OR_UPGRADE,
532 SCAN_AS_VIRTUAL_PRELOAD,
534 @Retention(RetentionPolicy.SOURCE)
535 public @interface ScanFlags {}
537 private static final String STATIC_SHARED_LIB_DELIMITER = "_";
538 /** Extension of the compressed packages */
539 public final static String COMPRESSED_EXTENSION = ".gz";
540 /** Suffix of stub packages on the system partition */
541 public final static String STUB_SUFFIX = "-Stub";
543 private static final int[] EMPTY_INT_ARRAY = new int[0];
545 private static final int TYPE_UNKNOWN = 0;
546 private static final int TYPE_ACTIVITY = 1;
547 private static final int TYPE_RECEIVER = 2;
548 private static final int TYPE_SERVICE = 3;
549 private static final int TYPE_PROVIDER = 4;
550 @IntDef(prefix = { "TYPE_" }, value = {
557 @Retention(RetentionPolicy.SOURCE)
558 public @interface ComponentType {}
561 * Timeout (in milliseconds) after which the watchdog should declare that
562 * our handler thread is wedged. The usual default for such things is one
563 * minute but we sometimes do very lengthy I/O operations on this thread,
564 * such as installing multi-gigabyte applications, so ours needs to be longer.
566 static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes
569 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
570 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
571 * settings entry if available, otherwise we use the hardcoded default. If it's been
572 * more than this long since the last fstrim, we force one during the boot sequence.
574 * This backstops other fstrim scheduling: if the device is alive at midnight+idle,
575 * one gets run at the next available charging+idle time. This final mandatory
576 * no-fstrim check kicks in only of the other scheduling criteria is never met.
578 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
581 * Whether verification is enabled by default.
583 private static final boolean DEFAULT_VERIFY_ENABLE = true;
586 * Whether integrity verification is enabled by default.
588 private static final boolean DEFAULT_INTEGRITY_VERIFY_ENABLE = true;
591 * The default maximum time to wait for the verification agent to return in
594 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
597 * Timeout duration in milliseconds for enabling package rollback. If we fail to enable
598 * rollback within that period, the install will proceed without rollback enabled.
600 * <p>If flag value is negative, the default value will be assigned.
602 * Flag type: {@code long}
603 * Namespace: NAMESPACE_ROLLBACK
605 private static final String PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS = "enable_rollback_timeout";
608 * The default duration to wait for rollback to be enabled in
611 private static final long DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS = 10 * 1000;
614 * The default response for package verification timeout.
616 * This can be either PackageManager.VERIFICATION_ALLOW or
617 * PackageManager.VERIFICATION_REJECT.
619 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
621 public static final String PLATFORM_PACKAGE_NAME = "android";
623 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
625 private static final String PACKAGE_SCHEME = "package";
627 /** Canonical intent used to identify what counts as a "web browser" app */
628 private static final Intent sBrowserIntent;
630 sBrowserIntent = new Intent();
631 sBrowserIntent.setAction(Intent.ACTION_VIEW);
632 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
633 sBrowserIntent.setData(Uri.parse("http:"));
634 sBrowserIntent.addFlags(Intent.FLAG_IGNORE_EPHEMERAL);
637 // Compilation reasons.
638 public static final int REASON_UNKNOWN = -1;
639 public static final int REASON_FIRST_BOOT = 0;
640 public static final int REASON_BOOT = 1;
641 public static final int REASON_INSTALL = 2;
642 public static final int REASON_BACKGROUND_DEXOPT = 3;
643 public static final int REASON_AB_OTA = 4;
644 public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
645 public static final int REASON_SHARED = 6;
647 public static final int REASON_LAST = REASON_SHARED;
650 * The initial enabled state of the cache before other checks are done.
652 private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
655 * Whether to skip all other checks and force the cache to be enabled.
657 * Setting this to true will cause the cache to be named "debug" to avoid eviction from
658 * build fingerprint changes.
660 private static final boolean FORCE_PACKAGE_PARSED_CACHE_ENABLED = false;
663 * Permissions required in order to receive instant application lifecycle broadcasts.
665 private static final String[] INSTANT_APP_BROADCAST_PERMISSION =
666 new String[] { android.Manifest.permission.ACCESS_INSTANT_APPS };
668 private static final String RANDOM_DIR_PREFIX = "~~";
670 final ServiceThread mHandlerThread;
672 final PackageHandler mHandler;
674 private final ProcessLoggingHandler mProcessLoggingHandler;
676 final int mSdkVersion = Build.VERSION.SDK_INT;
678 final Context mContext;
679 final boolean mFactoryTest;
680 final boolean mOnlyCore;
681 final DisplayMetrics mMetrics;
682 final int mDefParseFlags;
683 final String[] mSeparateProcesses;
684 final boolean mIsUpgrade;
685 final boolean mIsPreNUpgrade;
686 final boolean mIsPreNMR1Upgrade;
687 final boolean mIsPreQUpgrade;
690 private boolean mDexOptDialogShown;
692 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
693 // LOCK HELD. Can be called with mInstallLock held.
694 @GuardedBy("mInstallLock")
695 final Installer mInstaller;
697 /** Directory where installed applications are stored */
698 private static final File sAppInstallDir =
699 new File(Environment.getDataDirectory(), "app");
700 /** Directory where installed application's 32-bit native libraries are copied. */
702 static final File sAppLib32InstallDir =
703 new File(Environment.getDataDirectory(), "app-lib");
705 // ----------------------------------------------------------------
707 // Lock for state used when installing and doing other long running
708 // operations. Methods that must be called with this lock held have
710 final Object mInstallLock;
712 // ----------------------------------------------------------------
714 // Lock for global state used when modifying package state or settings.
715 // Methods that must be called with this lock held have
716 // the suffix "Locked". Some methods may use the legacy suffix "LP"
719 // Keys are String (package name), values are Package.
721 final ArrayMap<String, AndroidPackage> mPackages = new ArrayMap<>();
723 // Keys are isolated uids and values are the uid of the application
724 // that created the isolated proccess.
726 final SparseIntArray mIsolatedOwners = new SparseIntArray();
729 * Tracks new system packages [received in an OTA] that we expect to
730 * find updated user-installed versions. Keys are package name, values
731 * are package location.
733 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
736 * Tracks existing system packages prior to receiving an OTA. Keys are package name.
738 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
740 * Whether or not system app permissions should be promoted from install to runtime.
742 boolean mPromoteSystemApps;
744 private final PackageManagerInternal mPmInternal;
748 final Settings mSettings;
751 * Set of package names that are currently "frozen", which means active
752 * surgery is being done on the code/data for that package. The platform
753 * will refuse to launch frozen packages to avoid race conditions.
755 * @see PackageFreezer
758 final ArraySet<String> mFrozenPackages = new ArraySet<>();
760 final ProtectedPackages mProtectedPackages;
762 @GuardedBy("mLoadedVolumes")
763 final ArraySet<String> mLoadedVolumes = new ArraySet<>();
767 PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
769 @GuardedBy("mAvailableFeatures")
770 final ArrayMap<String, FeatureInfo> mAvailableFeatures;
772 private final InstantAppRegistry mInstantAppRegistry;
775 int mChangedPackagesSequenceNumber;
777 * List of changed [installed, removed or updated] packages.
778 * mapping from user id -> sequence number -> package name
781 final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
783 * The sequence number of the last change to a package.
784 * mapping from user id -> package name -> sequence number
787 final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
790 final private ArraySet<PackageListObserver> mPackageListObservers = new ArraySet<>();
793 private final SparseIntArray mDefaultPermissionsGrantedUsers = new SparseIntArray();
795 private final ModuleInfoProvider mModuleInfoProvider;
797 private final ApexManager mApexManager;
799 private final Injector mInjector;
802 * The list of all system partitions that may contain packages in ascending order of
803 * specificity (the more generic, the earlier in the list a partition appears).
805 @VisibleForTesting(visibility = Visibility.PRIVATE)
806 public static final List<ScanPartition> SYSTEM_PARTITIONS = Collections.unmodifiableList(
807 PackagePartitions.getOrderedPartitions(ScanPartition::new));
809 private final List<ScanPartition> mDirsToScanAsSystem;
811 private final OverlayConfig mOverlayConfig;
814 * Unit tests will instantiate, extend and/or mock to mock dependencies / behaviors.
816 * NOTE: All getters should return the same instance for every call.
818 @VisibleForTesting(visibility = Visibility.PRIVATE)
819 public static class Injector {
821 @VisibleForTesting(visibility = Visibility.PRIVATE)
822 interface Producer<T> {
823 /** Produce an instance of type {@link T} */
824 T produce(Injector injector, PackageManagerService packageManager);
827 static class LocalServicesProducer<T> implements Producer<T> {
828 private final Class<T> mProducingClass;
829 LocalServicesProducer(Class<T> clazz) {
830 this.mProducingClass = clazz;
832 public T produce(Injector injector, PackageManagerService packageManager) {
833 return LocalServices.getService(mProducingClass);
837 static class SystemServiceProducer<T> implements Producer<T> {
838 private final Class<T> mProducingClass;
839 SystemServiceProducer(Class<T> clazz) {
840 this.mProducingClass = clazz;
842 public T produce(Injector injector, PackageManagerService packageManager) {
843 return packageManager.mContext.getSystemService(mProducingClass);
847 @VisibleForTesting(visibility = Visibility.PRIVATE)
848 static class Singleton<T> {
849 private final Producer<T> mProducer;
850 private volatile T mInstance = null;
851 Singleton(Producer<T> producer) {
852 this.mProducer = producer;
854 T get(Injector injector, PackageManagerService packageManagerService) {
855 if (mInstance == null) {
856 mInstance = mProducer.produce(injector, packageManagerService);
862 private PackageManagerService mPackageManager;
864 private final PackageAbiHelper mAbiHelper;
865 private final Context mContext;
866 private final Object mLock;
867 private final Installer mInstaller;
868 private final Object mInstallLock;
870 // ----- producers -----
871 private final Singleton<ComponentResolver> mComponentResolverProducer;
872 private final Singleton<PermissionManagerServiceInternal> mPermissionManagerProducer;
873 private final Singleton<UserManagerService> mUserManagerProducer;
874 private final Singleton<Settings> mSettingsProducer;
875 private final Singleton<ActivityTaskManagerInternal> mActivityTaskManagerProducer;
876 private final Singleton<DeviceIdleInternal> mLocalDeviceIdleController;
877 private final Singleton<StorageManagerInternal> mStorageManagerInternalProducer;
878 private final Singleton<NetworkPolicyManagerInternal> mNetworkPolicyManagerProducer;
879 private final Singleton<PermissionPolicyInternal> mPermissionPolicyProducer;
880 private final Singleton<DeviceStorageMonitorInternal> mDeviceStorageMonitorProducer;
881 private final Singleton<DisplayManager> mDisplayManagerProducer;
882 private final Singleton<StorageManager> mStorageManagerProducer;
883 private final Singleton<AppOpsManager> mAppOpsManagerProducer;
884 private final Singleton<AppsFilter> mAppsFilterProducer;
885 private final Singleton<PlatformCompat> mPlatformCompatProducer;
887 Injector(Context context, Object lock, Installer installer,
888 Object installLock, PackageAbiHelper abiHelper,
889 Producer<ComponentResolver> componentResolverProducer,
890 Producer<PermissionManagerServiceInternal> permissionManagerProducer,
891 Producer<UserManagerService> userManagerProducer,
892 Producer<Settings> settingsProducer,
893 Producer<ActivityTaskManagerInternal> activityTaskManagerProducer,
894 Producer<DeviceIdleInternal> deviceIdleControllerProducer,
895 Producer<StorageManagerInternal> storageManagerInternalProducer,
896 Producer<NetworkPolicyManagerInternal> networkPolicyManagerProducer,
897 Producer<PermissionPolicyInternal> permissionPolicyProvider,
898 Producer<DeviceStorageMonitorInternal> deviceStorageMonitorProducer,
899 Producer<DisplayManager> displayManagerProducer,
900 Producer<StorageManager> storageManagerProducer,
901 Producer<AppOpsManager> appOpsManagerProducer,
902 Producer<AppsFilter> appsFilterProducer,
903 Producer<PlatformCompat> platformCompatProducer) {
906 mInstaller = installer;
907 mAbiHelper = abiHelper;
908 mInstallLock = installLock;
909 mComponentResolverProducer = new Singleton<>(componentResolverProducer);
910 mPermissionManagerProducer = new Singleton<>(permissionManagerProducer);
911 mUserManagerProducer = new Singleton<>(userManagerProducer);
912 mSettingsProducer = new Singleton<>(settingsProducer);
913 mActivityTaskManagerProducer = new Singleton<>(activityTaskManagerProducer);
914 mLocalDeviceIdleController = new Singleton<>(deviceIdleControllerProducer);
915 mStorageManagerInternalProducer = new Singleton<>(storageManagerInternalProducer);
916 mNetworkPolicyManagerProducer = new Singleton<>(networkPolicyManagerProducer);
917 mPermissionPolicyProducer = new Singleton<>(permissionPolicyProvider);
918 mDeviceStorageMonitorProducer = new Singleton<>(deviceStorageMonitorProducer);
919 mDisplayManagerProducer = new Singleton<>(displayManagerProducer);
920 mStorageManagerProducer = new Singleton<>(storageManagerProducer);
921 mAppOpsManagerProducer = new Singleton<>(appOpsManagerProducer);
922 mAppsFilterProducer = new Singleton<>(appsFilterProducer);
923 mPlatformCompatProducer = new Singleton<>(platformCompatProducer);
927 * Bootstraps this injector with the {@link PackageManagerService instance to which it
930 public void bootstrap(PackageManagerService pm) {
931 this.mPackageManager = pm;
934 public UserManagerInternal getUserManagerInternal() {
935 return getUserManagerService().getInternalForInjectorOnly();
938 public PackageAbiHelper getAbiHelper() {
942 public Object getInstallLock() {
946 public UserManagerService getUserManagerService() {
947 return mUserManagerProducer.get(this, mPackageManager);
950 public Object getLock() {
954 public Installer getInstaller() {
958 public ComponentResolver getComponentResolver() {
959 return mComponentResolverProducer.get(this, mPackageManager);
962 public PermissionManagerServiceInternal getPermissionManagerServiceInternal() {
963 return mPermissionManagerProducer.get(this, mPackageManager);
966 public Context getContext() {
970 public Settings getSettings() {
971 return mSettingsProducer.get(this, mPackageManager);
974 public ActivityTaskManagerInternal getActivityTaskManagerInternal() {
975 return mActivityTaskManagerProducer.get(this, mPackageManager);
978 public DeviceIdleInternal getLocalDeviceIdleController() {
979 return mLocalDeviceIdleController.get(this, mPackageManager);
982 public StorageManagerInternal getStorageManagerInternal() {
983 return mStorageManagerInternalProducer.get(this, mPackageManager);
986 public NetworkPolicyManagerInternal getNetworkPolicyManagerInternal() {
987 return mNetworkPolicyManagerProducer.get(this, mPackageManager);
990 public PermissionPolicyInternal getPermissionPolicyInternal() {
991 return mPermissionPolicyProducer.get(this, mPackageManager);
994 public DeviceStorageMonitorInternal getDeviceStorageMonitorInternal() {
995 return mDeviceStorageMonitorProducer.get(this, mPackageManager);
998 public DisplayManager getDisplayManager() {
999 return mDisplayManagerProducer.get(this, mPackageManager);
1002 public StorageManager getStorageManager() {
1003 return mStorageManagerProducer.get(this, mPackageManager);
1006 public AppOpsManager getAppOpsManager() {
1007 return mAppOpsManagerProducer.get(this, mPackageManager);
1010 public AppsFilter getAppsFilter() {
1011 return mAppsFilterProducer.get(this, mPackageManager);
1014 public PlatformCompat getCompatibility() {
1015 return mPlatformCompatProducer.get(this, mPackageManager);
1019 private final AppsFilter mAppsFilter;
1021 class PackageParserCallback extends PackageParser2.Callback {
1022 @Override public final boolean hasFeature(String feature) {
1023 return PackageManagerService.this.hasSystemFeature(feature, 0);
1027 final PackageParser2.Callback mPackageParserCallback = new PackageParserCallback();
1029 // Currently known shared libraries.
1030 final ArrayMap<String, LongSparseArray<SharedLibraryInfo>> mSharedLibraries = new ArrayMap<>();
1031 final ArrayMap<String, LongSparseArray<SharedLibraryInfo>> mStaticLibsByDeclaringPackage =
1034 // Mapping from instrumentation class names to info about them.
1035 final ArrayMap<ComponentName, ParsedInstrumentation> mInstrumentation =
1038 // Packages whose data we have transfered into another package, thus
1039 // should no longer exist.
1040 final ArraySet<String> mTransferredPackages = new ArraySet<>();
1042 // Broadcast actions that are only available to the system.
1043 @GuardedBy("mProtectedBroadcasts")
1044 final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
1046 /** List of packages waiting for verification. */
1047 final SparseArray<PackageVerificationState> mPendingVerification = new SparseArray<>();
1049 /** List of packages waiting for rollback to be enabled. */
1050 final SparseArray<InstallParams> mPendingEnableRollback = new SparseArray<>();
1052 final PackageInstallerService mInstallerService;
1054 final ArtManagerService mArtManagerService;
1056 private final PackageDexOptimizer mPackageDexOptimizer;
1057 // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
1058 // is used by other apps).
1059 private final DexManager mDexManager;
1061 private final ViewCompiler mViewCompiler;
1063 private AtomicInteger mNextMoveId = new AtomicInteger();
1064 private final MoveCallbacks mMoveCallbacks;
1066 // Cache of users who need badging.
1067 private final SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
1069 /** Token for keys in mPendingVerification. */
1070 private int mPendingVerificationToken = 0;
1072 /** Token for keys in mPendingEnableRollback. */
1073 private int mPendingEnableRollbackToken = 0;
1075 volatile boolean mSystemReady;
1076 volatile boolean mSafeMode;
1077 volatile boolean mHasSystemUidErrors;
1078 private volatile SparseBooleanArray mWebInstantAppsDisabled = new SparseBooleanArray();
1080 ApplicationInfo mAndroidApplication;
1081 final ActivityInfo mResolveActivity = new ActivityInfo();
1082 final ResolveInfo mResolveInfo = new ResolveInfo();
1083 ComponentName mResolveComponentName;
1084 AndroidPackage mPlatformPackage;
1085 ComponentName mCustomResolverComponentName;
1087 boolean mResolverReplaced = false;
1089 private final @Nullable ComponentName mIntentFilterVerifierComponent;
1090 private final @Nullable IntentFilterVerifier<ParsedIntentInfo> mIntentFilterVerifier;
1092 private int mIntentFilterVerificationToken = 0;
1094 /** The service connection to the ephemeral resolver */
1095 final InstantAppResolverConnection mInstantAppResolverConnection;
1096 /** Component used to show resolver settings for Instant Apps */
1097 final ComponentName mInstantAppResolverSettingsComponent;
1099 /** Activity used to install instant applications */
1100 ActivityInfo mInstantAppInstallerActivity;
1101 final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
1103 private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
1104 mNoKillInstallObservers = Collections.synchronizedMap(new HashMap<>());
1106 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
1107 = new SparseArray<>();
1109 // Internal interface for permission manager
1110 private final PermissionManagerServiceInternal mPermissionManager;
1111 // Public interface for permission manager
1112 private final IPermissionManager mPermissionManagerService;
1114 private final ComponentResolver mComponentResolver;
1115 // List of packages names to keep cached, even if they are uninstalled for all users
1116 private List<String> mKeepUninstalledPackages;
1118 private File mCacheDir;
1120 private Future<?> mPrepareAppDataFuture;
1122 private final IncrementalManager mIncrementalManager;
1124 private static class IFVerificationParams {
1126 boolean hasDomainUrls;
1127 List<ParsedActivity> activities;
1132 public IFVerificationParams(String packageName, boolean hasDomainUrls,
1133 List<ParsedActivity> activities, boolean _replacing,
1134 int _userId, int _verifierUid) {
1135 this.packageName = packageName;
1136 this.hasDomainUrls = hasDomainUrls;
1137 this.activities = activities;
1138 replacing = _replacing;
1140 verifierUid = _verifierUid;
1144 private interface IntentFilterVerifier<T extends IntentFilter> {
1145 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1146 T filter, String packageName);
1147 void startVerifications(int userId);
1148 void receiveVerificationResponse(int verificationId);
1151 private class IntentVerifierProxy implements IntentFilterVerifier<ParsedIntentInfo> {
1152 private Context mContext;
1153 private ComponentName mIntentFilterVerifierComponent;
1154 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<>();
1156 public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1158 mIntentFilterVerifierComponent = verifierComponent;
1161 private String getDefaultScheme() {
1162 return IntentFilter.SCHEME_HTTPS;
1166 public void startVerifications(int userId) {
1167 // Launch verifications requests
1168 int count = mCurrentIntentFilterVerifications.size();
1169 for (int n=0; n<count; n++) {
1170 int verificationId = mCurrentIntentFilterVerifications.get(n);
1171 final IntentFilterVerificationState ivs =
1172 mIntentFilterVerificationStates.get(verificationId);
1174 String packageName = ivs.getPackageName();
1176 ArrayList<ParsedIntentInfo> filters = ivs.getFilters();
1177 final int filterCount = filters.size();
1178 ArraySet<String> domainsSet = new ArraySet<>();
1179 for (int m=0; m<filterCount; m++) {
1180 ParsedIntentInfo filter = filters.get(m);
1181 domainsSet.addAll(filter.getHostsList());
1183 synchronized (mLock) {
1184 if (mSettings.createIntentFilterVerificationIfNeededLPw(
1185 packageName, domainsSet) != null) {
1186 scheduleWriteSettingsLocked();
1189 sendVerificationRequest(verificationId, ivs);
1191 mCurrentIntentFilterVerifications.clear();
1194 private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1195 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1196 verificationIntent.putExtra(
1197 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1199 verificationIntent.putExtra(
1200 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1201 getDefaultScheme());
1202 verificationIntent.putExtra(
1203 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1204 ivs.getHostsString());
1205 verificationIntent.putExtra(
1206 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1207 ivs.getPackageName());
1208 verificationIntent.setComponent(mIntentFilterVerifierComponent);
1209 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1211 final long whitelistTimeout = getVerificationTimeout();
1212 final BroadcastOptions options = BroadcastOptions.makeBasic();
1213 options.setTemporaryAppWhitelistDuration(whitelistTimeout);
1215 DeviceIdleInternal idleController =
1216 mInjector.getLocalDeviceIdleController();
1217 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1218 mIntentFilterVerifierComponent.getPackageName(), whitelistTimeout,
1219 UserHandle.USER_SYSTEM, true, "intent filter verifier");
1221 mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM,
1222 null, options.toBundle());
1223 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1224 "Sending IntentFilter verification broadcast");
1227 public void receiveVerificationResponse(int verificationId) {
1228 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1230 final boolean verified = ivs.isVerified();
1232 ArrayList<ParsedIntentInfo> filters = ivs.getFilters();
1233 final int count = filters.size();
1234 if (DEBUG_DOMAIN_VERIFICATION) {
1235 Slog.i(TAG, "Received verification response " + verificationId
1236 + " for " + count + " filters, verified=" + verified);
1238 for (int n=0; n<count; n++) {
1239 ParsedIntentInfo filter = filters.get(n);
1240 filter.setVerified(verified);
1242 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1243 + " verified with result:" + verified + " and hosts:"
1244 + ivs.getHostsString());
1247 mIntentFilterVerificationStates.remove(verificationId);
1249 final String packageName = ivs.getPackageName();
1250 IntentFilterVerificationInfo ivi;
1252 synchronized (mLock) {
1253 ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1256 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1257 + verificationId + " packageName:" + packageName);
1261 synchronized (mLock) {
1263 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1265 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1267 scheduleWriteSettingsLocked();
1269 final int userId = ivs.getUserId();
1270 if (userId != UserHandle.USER_ALL) {
1271 final int userStatus =
1272 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1274 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1275 boolean needUpdate = false;
1277 if (DEBUG_DOMAIN_VERIFICATION) {
1279 "Updating IntentFilterVerificationInfo for package " + packageName
1280 + " verificationId:" + verificationId
1281 + " verified=" + verified);
1284 // In a success case, we promote from undefined or ASK to ALWAYS. This
1285 // supports a flow where the app fails validation but then ships an updated
1286 // APK that passes, and therefore deserves to be in ALWAYS.
1288 // If validation failed, the undefined state winds up in the basic ASK behavior,
1289 // but apps that previously passed and became ALWAYS are *demoted* out of
1290 // that state, since they would not deserve the ALWAYS behavior in case of a
1292 switch (userStatus) {
1293 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
1295 // Don't demote if sysconfig says 'always'
1296 SystemConfig systemConfig = SystemConfig.getInstance();
1297 ArraySet<String> packages = systemConfig.getLinkedApps();
1298 if (!packages.contains(packageName)) {
1299 // updatedStatus is already UNDEFINED
1302 if (DEBUG_DOMAIN_VERIFICATION) {
1303 Slog.d(TAG, "Formerly validated but now failing; demoting");
1306 if (DEBUG_DOMAIN_VERIFICATION) {
1307 Slog.d(TAG, "Updating bundled package " + packageName
1308 + " failed autoVerify, but sysconfig supersedes");
1310 // leave needUpdate == false here intentionally
1315 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1316 // Stay in 'undefined' on verification failure
1318 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1321 if (DEBUG_DOMAIN_VERIFICATION) {
1322 Slog.d(TAG, "Applying update; old=" + userStatus
1323 + " new=" + updatedStatus);
1327 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1328 // Keep in 'ask' on failure
1330 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1340 mSettings.updateIntentFilterVerificationStatusLPw(
1341 packageName, updatedStatus, userId);
1342 scheduleWritePackageRestrictionsLocked(userId);
1345 Slog.i(TAG, "autoVerify ignored when installing for all users");
1351 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1352 ParsedIntentInfo filter, String packageName) {
1353 if (!hasValidDomains(filter)) {
1356 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1358 ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1361 if (DEBUG_DOMAIN_VERIFICATION) {
1362 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1364 ivs.addFilter(filter);
1368 private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1369 int userId, int verificationId, String packageName) {
1370 IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1371 verifierUid, userId, packageName);
1372 ivs.setPendingState();
1373 synchronized (mLock) {
1374 mIntentFilterVerificationStates.append(verificationId, ivs);
1375 mCurrentIntentFilterVerifications.add(verificationId);
1381 private static boolean hasValidDomains(ParsedIntentInfo filter) {
1382 return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1383 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1384 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1387 // Set of pending broadcasts for aggregating enable/disable of components.
1388 static class PendingPackageBroadcasts {
1389 // for each user id, a map of <package name -> components within that package>
1390 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1392 public PendingPackageBroadcasts() {
1393 mUidMap = new SparseArray<>(2);
1396 public ArrayList<String> get(int userId, String packageName) {
1397 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1398 return packages.get(packageName);
1401 public void put(int userId, String packageName, ArrayList<String> components) {
1402 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1403 packages.put(packageName, components);
1406 public void remove(int userId, String packageName) {
1407 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1408 if (packages != null) {
1409 packages.remove(packageName);
1413 public void remove(int userId) {
1414 mUidMap.remove(userId);
1417 public int userIdCount() {
1418 return mUidMap.size();
1421 public int userIdAt(int n) {
1422 return mUidMap.keyAt(n);
1425 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1426 return mUidMap.get(userId);
1430 // total number of pending broadcast entries across all userIds
1432 for (int i = 0; i< mUidMap.size(); i++) {
1433 num += mUidMap.valueAt(i).size();
1438 public void clear() {
1442 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1443 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1445 map = new ArrayMap<>();
1446 mUidMap.put(userId, map);
1451 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1453 static final int SEND_PENDING_BROADCAST = 1;
1454 static final int INIT_COPY = 5;
1455 static final int POST_INSTALL = 9;
1456 static final int WRITE_SETTINGS = 13;
1457 static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1458 static final int PACKAGE_VERIFIED = 15;
1459 static final int CHECK_PENDING_VERIFICATION = 16;
1460 static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1461 static final int INTENT_FILTER_VERIFIED = 18;
1462 static final int WRITE_PACKAGE_LIST = 19;
1463 static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1464 static final int ENABLE_ROLLBACK_STATUS = 21;
1465 static final int ENABLE_ROLLBACK_TIMEOUT = 22;
1466 static final int DEFERRED_NO_KILL_POST_DELETE = 23;
1467 static final int DEFERRED_NO_KILL_INSTALL_OBSERVER = 24;
1468 static final int INTEGRITY_VERIFICATION_COMPLETE = 25;
1469 static final int CHECK_PENDING_INTEGRITY_VERIFICATION = 26;
1471 static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
1472 static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
1474 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds
1476 private static final long BROADCAST_DELAY_DURING_STARTUP = 10 * 1000L; // 10 seconds (in millis)
1477 private static final long BROADCAST_DELAY = 1 * 1000L; // 1 second (in millis)
1479 // When the service constructor finished plus a delay (used for broadcast delay computation)
1480 private long mServiceStartWithDelay;
1482 private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1483 2 * 60 * 60 * 1000L; /* two hours */
1485 UserManagerService mUserManager;
1487 // Stores a list of users whose package restrictions file needs to be updated
1488 private ArraySet<Integer> mDirtyUsers = new ArraySet<>();
1490 // Recordkeeping of restore-after-install operations that are currently in flight
1491 // between the Package Manager and the Backup Manager
1492 static class PostInstallData {
1493 public final InstallArgs args;
1494 public final PackageInstalledInfo res;
1495 public final Runnable mPostInstallRunnable;
1497 PostInstallData(InstallArgs _a, PackageInstalledInfo _r, Runnable postInstallRunnable) {
1500 mPostInstallRunnable = postInstallRunnable;
1504 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<>();
1505 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows
1507 // XML tags for backup/restore of various bits of state
1508 private static final String TAG_PREFERRED_BACKUP = "pa";
1509 private static final String TAG_DEFAULT_APPS = "da";
1510 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1512 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1513 private static final String TAG_ALL_GRANTS = "rt-grants";
1514 private static final String TAG_GRANT = "grant";
1515 private static final String ATTR_PACKAGE_NAME = "pkg";
1517 private static final String TAG_PERMISSION = "perm";
1518 private static final String ATTR_PERMISSION_NAME = "name";
1519 private static final String ATTR_IS_GRANTED = "g";
1520 private static final String ATTR_USER_SET = "set";
1521 private static final String ATTR_USER_FIXED = "fixed";
1522 private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1524 // System/policy permission grants are not backed up
1525 private static final int SYSTEM_RUNTIME_GRANT_MASK =
1526 FLAG_PERMISSION_POLICY_FIXED
1527 | FLAG_PERMISSION_SYSTEM_FIXED
1528 | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1530 // And we back up these user-adjusted states
1531 private static final int USER_RUNTIME_GRANT_MASK =
1532 FLAG_PERMISSION_USER_SET
1533 | FLAG_PERMISSION_USER_FIXED
1534 | FLAG_PERMISSION_REVOKED_COMPAT;
1536 final @Nullable String mRequiredVerifierPackage;
1537 final @NonNull String mRequiredInstallerPackage;
1538 final @NonNull String mRequiredUninstallerPackage;
1539 final @NonNull String mRequiredPermissionControllerPackage;
1540 final @Nullable String mSetupWizardPackage;
1541 final @Nullable String mStorageManagerPackage;
1542 final @Nullable String mDefaultTextClassifierPackage;
1543 final @Nullable String mSystemTextClassifierPackageName;
1544 final @Nullable String mWellbeingPackage;
1545 final @Nullable String mDocumenterPackage;
1546 final @Nullable String mConfiguratorPackage;
1547 final @Nullable String mAppPredictionServicePackage;
1548 final @Nullable String mIncidentReportApproverPackage;
1549 final @Nullable String[] mTelephonyPackages;
1550 final @Nullable String mServicesExtensionPackageName;
1551 final @Nullable String mSharedSystemSharedLibraryPackageName;
1552 final @Nullable String mRetailDemoPackage;
1554 private final PackageUsage mPackageUsage = new PackageUsage();
1555 private final CompilerStats mCompilerStats = new CompilerStats();
1557 class PackageHandler extends Handler {
1559 PackageHandler(Looper looper) {
1563 public void handleMessage(Message msg) {
1565 doHandleMessage(msg);
1567 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1571 void doHandleMessage(Message msg) {
1574 HandlerParams params = (HandlerParams) msg.obj;
1575 if (params != null) {
1576 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy: " + params);
1577 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1578 System.identityHashCode(params));
1579 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1581 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1585 case SEND_PENDING_BROADCAST: {
1587 ArrayList<String> components[];
1590 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1591 synchronized (mLock) {
1592 size = mPendingBroadcasts.size();
1594 // Nothing to be done. Just return
1597 packages = new String[size];
1598 components = new ArrayList[size];
1599 uids = new int[size];
1600 int i = 0; // filling out the above arrays
1602 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1603 int packageUserId = mPendingBroadcasts.userIdAt(n);
1604 Iterator<Map.Entry<String, ArrayList<String>>> it
1605 = mPendingBroadcasts.packagesForUserId(packageUserId)
1606 .entrySet().iterator();
1607 while (it.hasNext() && i < size) {
1608 Map.Entry<String, ArrayList<String>> ent = it.next();
1609 packages[i] = ent.getKey();
1610 components[i] = ent.getValue();
1611 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1612 uids[i] = (ps != null)
1613 ? UserHandle.getUid(packageUserId, ps.appId)
1619 mPendingBroadcasts.clear();
1622 for (int i = 0; i < size; i++) {
1623 sendPackageChangedBroadcast(packages[i], true /* dontKillApp */,
1624 components[i], uids[i], null /* reason */);
1626 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1629 case POST_INSTALL: {
1630 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1632 PostInstallData data = mRunningInstalls.get(msg.arg1);
1633 final boolean didRestore = (msg.arg2 != 0);
1634 mRunningInstalls.delete(msg.arg1);
1636 if (data != null && data.res.freezer != null) {
1637 data.res.freezer.close();
1640 if (data != null && data.mPostInstallRunnable != null) {
1641 data.mPostInstallRunnable.run();
1642 } else if (data != null) {
1643 InstallArgs args = data.args;
1644 PackageInstalledInfo parentRes = data.res;
1646 final boolean grantPermissions = (args.installFlags
1647 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1648 final boolean killApp = (args.installFlags
1649 & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1650 final boolean virtualPreload = ((args.installFlags
1651 & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1652 final String[] grantedPermissions = args.installGrantPermissions;
1653 final List<String> whitelistedRestrictedPermissions = ((args.installFlags
1654 & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0
1655 && parentRes.pkg != null)
1656 ? parentRes.pkg.getRequestedPermissions()
1657 : args.whitelistedRestrictedPermissions;
1659 // Handle the parent package
1660 handlePackagePostInstall(parentRes, grantPermissions,
1661 killApp, virtualPreload, grantedPermissions,
1662 whitelistedRestrictedPermissions, didRestore,
1663 args.installSource.installerPackageName, args.observer,
1664 args.mDataLoaderType);
1666 // Handle the child packages
1667 final int childCount = (parentRes.addedChildPackages != null)
1668 ? parentRes.addedChildPackages.size() : 0;
1669 for (int i = 0; i < childCount; i++) {
1670 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1671 handlePackagePostInstall(childRes, grantPermissions,
1672 killApp, virtualPreload, grantedPermissions,
1673 whitelistedRestrictedPermissions, false /*didRestore*/,
1674 args.installSource.installerPackageName, args.observer,
1675 args.mDataLoaderType);
1678 // Log tracing if needed
1679 if (args.traceMethod != null) {
1680 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1683 } else if (DEBUG_INSTALL) {
1684 // No post-install when we run restore from installExistingPackageForUser
1685 Slog.i(TAG, "Nothing to do for post-install token " + msg.arg1);
1688 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1690 case DEFERRED_NO_KILL_POST_DELETE: {
1691 synchronized (mInstallLock) {
1692 InstallArgs args = (InstallArgs) msg.obj;
1694 args.doPostDeleteLI(true);
1698 case DEFERRED_NO_KILL_INSTALL_OBSERVER: {
1699 String packageName = (String) msg.obj;
1700 if (packageName != null) {
1701 notifyInstallObserver(packageName);
1704 case WRITE_SETTINGS: {
1705 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1706 synchronized (mLock) {
1707 removeMessages(WRITE_SETTINGS);
1708 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1709 mSettings.writeLPr();
1710 mDirtyUsers.clear();
1712 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1714 case WRITE_PACKAGE_RESTRICTIONS: {
1715 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1716 synchronized (mLock) {
1717 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1718 for (int userId : mDirtyUsers) {
1719 mSettings.writePackageRestrictionsLPr(userId);
1721 mDirtyUsers.clear();
1723 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1725 case WRITE_PACKAGE_LIST: {
1726 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1727 synchronized (mLock) {
1728 removeMessages(WRITE_PACKAGE_LIST);
1729 mSettings.writePackageListLPr(msg.arg1);
1731 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1733 case CHECK_PENDING_VERIFICATION: {
1734 final int verificationId = msg.arg1;
1735 final PackageVerificationState state = mPendingVerification.get(verificationId);
1737 if ((state != null) && !state.isVerificationComplete()
1738 && !state.timeoutExtended()) {
1739 final InstallParams params = state.getInstallParams();
1740 final InstallArgs args = params.mArgs;
1741 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1743 Slog.i(TAG, "Verification timed out for " + originUri);
1745 final UserHandle user = args.getUser();
1746 if (getDefaultVerificationResponse(user)
1747 == PackageManager.VERIFICATION_ALLOW) {
1748 Slog.i(TAG, "Continuing with installation of " + originUri);
1749 state.setVerifierResponse(Binder.getCallingUid(),
1750 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1751 broadcastPackageVerified(verificationId, originUri,
1752 PackageManager.VERIFICATION_ALLOW, user);
1754 broadcastPackageVerified(verificationId, originUri,
1755 PackageManager.VERIFICATION_REJECT, user);
1756 params.setReturnCode(
1757 PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
1758 state.setVerifierResponse(Binder.getCallingUid(),
1759 PackageManager.VERIFICATION_REJECT);
1762 if (state.areAllVerificationsComplete()) {
1763 mPendingVerification.remove(verificationId);
1766 Trace.asyncTraceEnd(
1767 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1769 params.handleVerificationFinished();
1774 case CHECK_PENDING_INTEGRITY_VERIFICATION: {
1775 final int verificationId = msg.arg1;
1776 final PackageVerificationState state = mPendingVerification.get(verificationId);
1778 if (state != null && !state.isIntegrityVerificationComplete()) {
1779 final InstallParams params = state.getInstallParams();
1780 final InstallArgs args = params.mArgs;
1781 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1783 Slog.i(TAG, "Integrity verification timed out for " + originUri);
1785 state.setIntegrityVerificationResult(
1786 getDefaultIntegrityVerificationResponse());
1788 if (getDefaultIntegrityVerificationResponse()
1789 == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) {
1790 Slog.i(TAG, "Integrity check times out, continuing with " + originUri);
1792 params.setReturnCode(
1793 PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
1796 if (state.areAllVerificationsComplete()) {
1797 mPendingVerification.remove(verificationId);
1800 Trace.asyncTraceEnd(
1801 TRACE_TAG_PACKAGE_MANAGER,
1802 "integrity_verification",
1805 params.handleIntegrityVerificationFinished();
1809 case PACKAGE_VERIFIED: {
1810 final int verificationId = msg.arg1;
1812 final PackageVerificationState state = mPendingVerification.get(verificationId);
1813 if (state == null) {
1814 Slog.w(TAG, "Verification with id " + verificationId
1816 + " It may be invalid or overridden by integrity verification");
1820 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1822 state.setVerifierResponse(response.callerUid, response.code);
1824 if (state.isVerificationComplete()) {
1825 final InstallParams params = state.getInstallParams();
1826 final InstallArgs args = params.mArgs;
1827 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1829 if (state.isInstallAllowed()) {
1830 broadcastPackageVerified(verificationId, originUri,
1831 response.code, args.getUser());
1833 params.setReturnCode(
1834 PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
1837 if (state.areAllVerificationsComplete()) {
1838 mPendingVerification.remove(verificationId);
1841 Trace.asyncTraceEnd(
1842 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1844 params.handleVerificationFinished();
1849 case INTEGRITY_VERIFICATION_COMPLETE: {
1850 final int verificationId = msg.arg1;
1852 final PackageVerificationState state = mPendingVerification.get(verificationId);
1853 if (state == null) {
1854 Slog.w(TAG, "Integrity verification with id " + verificationId
1855 + " not found. It may be invalid or overridden by verifier");
1859 final int response = (Integer) msg.obj;
1861 final InstallParams params = state.getInstallParams();
1862 final InstallArgs args = params.mArgs;
1863 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1865 state.setIntegrityVerificationResult(response);
1867 if (response == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) {
1868 Slog.i(TAG, "Integrity check passed for " + originUri);
1870 params.setReturnCode(
1871 PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
1874 if (state.areAllVerificationsComplete()) {
1875 mPendingVerification.remove(verificationId);
1878 Trace.asyncTraceEnd(
1879 TRACE_TAG_PACKAGE_MANAGER,
1880 "integrity_verification",
1883 params.handleIntegrityVerificationFinished();
1886 case START_INTENT_FILTER_VERIFICATIONS: {
1887 IFVerificationParams params = (IFVerificationParams) msg.obj;
1888 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, params.replacing,
1889 params.packageName, params.hasDomainUrls, params.activities);
1892 case INTENT_FILTER_VERIFIED: {
1893 final int verificationId = msg.arg1;
1895 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1897 if (state == null) {
1898 Slog.w(TAG, "Invalid IntentFilter verification token "
1899 + verificationId + " received");
1903 final int userId = state.getUserId();
1905 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1906 "Processing IntentFilter verification with token:"
1907 + verificationId + " and userId:" + userId);
1909 final IntentFilterVerificationResponse response =
1910 (IntentFilterVerificationResponse) msg.obj;
1912 state.setVerifierResponse(response.callerUid, response.code);
1914 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1915 "IntentFilter verification with token:" + verificationId
1916 + " and userId:" + userId
1917 + " is settings verifier response with response code:"
1920 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1921 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1922 + response.getFailedDomainsString());
1925 if (state.isVerificationComplete()) {
1926 mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1928 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1929 "IntentFilter verification with token:" + verificationId
1930 + " was not said to be complete");
1935 case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1936 InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1937 mInstantAppResolverConnection,
1938 (InstantAppRequest) msg.obj,
1939 mInstantAppInstallerActivity,
1943 case ENABLE_ROLLBACK_STATUS: {
1944 final int enableRollbackToken = msg.arg1;
1945 final int enableRollbackCode = msg.arg2;
1946 InstallParams params = mPendingEnableRollback.get(enableRollbackToken);
1947 if (params == null) {
1948 Slog.w(TAG, "Invalid rollback enabled token "
1949 + enableRollbackToken + " received");
1953 mPendingEnableRollback.remove(enableRollbackToken);
1955 if (enableRollbackCode != PackageManagerInternal.ENABLE_ROLLBACK_SUCCEEDED) {
1956 final InstallArgs args = params.mArgs;
1957 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1958 Slog.w(TAG, "Failed to enable rollback for " + originUri);
1959 Slog.w(TAG, "Continuing with installation of " + originUri);
1962 Trace.asyncTraceEnd(
1963 TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
1965 params.handleRollbackEnabled();
1968 case ENABLE_ROLLBACK_TIMEOUT: {
1969 final int enableRollbackToken = msg.arg1;
1970 final InstallParams params = mPendingEnableRollback.get(enableRollbackToken);
1971 if (params != null) {
1972 final InstallArgs args = params.mArgs;
1973 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1975 Slog.w(TAG, "Enable rollback timed out for " + originUri);
1976 mPendingEnableRollback.remove(enableRollbackToken);
1978 Slog.w(TAG, "Continuing with installation of " + originUri);
1979 Trace.asyncTraceEnd(
1980 TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
1981 params.handleRollbackEnabled();
1982 Intent rollbackTimeoutIntent = new Intent(
1983 Intent.ACTION_CANCEL_ENABLE_ROLLBACK);
1984 rollbackTimeoutIntent.putExtra(
1985 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN,
1986 enableRollbackToken);
1987 rollbackTimeoutIntent.addFlags(
1988 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1989 mContext.sendBroadcastAsUser(rollbackTimeoutIntent, UserHandle.SYSTEM,
1990 android.Manifest.permission.PACKAGE_ROLLBACK_AGENT);
1998 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1999 boolean killApp, boolean virtualPreload,
2000 String[] grantedPermissions, List<String> whitelistedRestrictedPermissions,
2001 boolean launchedForRestore, String installerPackage,
2002 IPackageInstallObserver2 installObserver, int dataLoaderType) {
2003 final boolean succeeded = res.returnCode == PackageManager.INSTALL_SUCCEEDED;
2004 final boolean update = res.removedInfo != null && res.removedInfo.removedPackage != null;
2007 // Send the removed broadcasts
2008 if (res.removedInfo != null) {
2009 res.removedInfo.sendPackageRemovedBroadcasts(killApp);
2012 // Whitelist any restricted permissions first as some may be runtime
2013 // that the installer requested to be granted at install time.
2014 if (whitelistedRestrictedPermissions != null
2015 && !whitelistedRestrictedPermissions.isEmpty()) {
2016 mPermissionManager.setWhitelistedRestrictedPermissions(
2017 res.pkg, res.newUsers, whitelistedRestrictedPermissions,
2018 Process.myUid(), FLAG_PERMISSION_WHITELIST_INSTALLER);
2021 // Now that we successfully installed the package, grant runtime
2022 // permissions if requested before broadcasting the install. Also
2023 // for legacy apps in permission review mode we clear the permission
2024 // review flag which is used to emulate runtime permissions for
2026 if (grantPermissions) {
2027 final int callingUid = Binder.getCallingUid();
2028 mPermissionManager.grantRequestedRuntimePermissions(
2029 res.pkg, res.newUsers, grantedPermissions, callingUid);
2032 final String installerPackageName =
2033 res.installerPackageName != null
2034 ? res.installerPackageName
2035 : res.removedInfo != null
2036 ? res.removedInfo.installerPackageName
2039 synchronized (mLock) {
2040 mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
2043 final String packageName = res.pkg.getPackageName();
2045 // Determine the set of users who are adding this package for
2046 // the first time vs. those who are seeing an update.
2047 int[] firstUserIds = EMPTY_INT_ARRAY;
2048 int[] firstInstantUserIds = EMPTY_INT_ARRAY;
2049 int[] updateUserIds = EMPTY_INT_ARRAY;
2050 int[] instantUserIds = EMPTY_INT_ARRAY;
2051 final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
2052 final PackageSetting ps = getPackageSetting(res.pkg.getPackageName());
2053 for (int newUser : res.newUsers) {
2054 final boolean isInstantApp = ps.getInstantApp(newUser);
2057 firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2059 firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2063 boolean isNew = true;
2064 for (int origUser : res.origUsers) {
2065 if (origUser == newUser) {
2072 firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2074 firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2078 instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
2080 updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
2085 // Send installed broadcasts if the package is not a static shared lib.
2086 if (res.pkg.getStaticSharedLibName() == null) {
2087 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(
2088 res.pkg.getBaseCodePath());
2090 // Send added for users that see the package for the first time
2091 // sendPackageAddedForNewUsers also deals with system apps
2092 int appId = UserHandle.getAppId(res.uid);
2093 boolean isSystem = res.pkg.isSystem();
2094 sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
2095 virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds);
2097 // Send added for users that don't see the package for the first time
2098 Bundle extras = new Bundle(1);
2099 extras.putInt(Intent.EXTRA_UID, res.uid);
2101 extras.putBoolean(Intent.EXTRA_REPLACING, true);
2103 extras.putInt(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType);
2104 // Send to all running apps.
2105 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2106 extras, 0 /*flags*/,
2107 null /*targetPackage*/, null /*finishedReceiver*/,
2108 updateUserIds, instantUserIds);
2109 if (installerPackageName != null) {
2110 // Send to the installer, even if it's not running.
2111 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2112 extras, 0 /*flags*/,
2113 installerPackageName, null /*finishedReceiver*/,
2114 updateUserIds, instantUserIds);
2116 // if the required verifier is defined, but, is not the installer of record
2117 // for the package, it gets notified
2118 final boolean notifyVerifier = mRequiredVerifierPackage != null
2119 && !mRequiredVerifierPackage.equals(installerPackageName);
2120 if (notifyVerifier) {
2121 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2122 extras, 0 /*flags*/,
2123 mRequiredVerifierPackage, null /*finishedReceiver*/,
2124 updateUserIds, instantUserIds);
2126 // If package installer is defined, notify package installer about new
2128 if (mRequiredInstallerPackage != null) {
2129 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2130 extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND /*flags*/,
2131 mRequiredInstallerPackage, null /*finishedReceiver*/,
2132 firstUserIds, instantUserIds);
2135 // Send replaced for users that don't see the package for the first time
2137 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2138 packageName, extras, 0 /*flags*/,
2139 null /*targetPackage*/, null /*finishedReceiver*/,
2140 updateUserIds, instantUserIds);
2141 if (installerPackageName != null) {
2142 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2143 extras, 0 /*flags*/,
2144 installerPackageName, null /*finishedReceiver*/,
2145 updateUserIds, instantUserIds);
2147 if (notifyVerifier) {
2148 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2149 extras, 0 /*flags*/,
2150 mRequiredVerifierPackage, null /*finishedReceiver*/,
2151 updateUserIds, instantUserIds);
2153 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2154 null /*package*/, null /*extras*/, 0 /*flags*/,
2155 packageName /*targetPackage*/,
2156 null /*finishedReceiver*/, updateUserIds, instantUserIds);
2157 } else if (launchedForRestore && !res.pkg.isSystem()) {
2158 // First-install and we did a restore, so we're responsible for the
2159 // first-launch broadcast.
2161 Slog.i(TAG, "Post-restore of " + packageName
2162 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds));
2164 sendFirstLaunchBroadcast(packageName, installerPackage,
2165 firstUserIds, firstInstantUserIds);
2168 // Send broadcast package appeared if external for all users
2169 if (res.pkg.isExternalStorage()) {
2171 final StorageManager storage = mInjector.getStorageManager();
2173 storage.findVolumeByUuid(
2174 res.pkg.getStorageUuid().toString());
2175 int packageExternalStorageType =
2176 getPackageExternalStorageType(volume, res.pkg.isExternalStorage());
2177 // If the package was installed externally, log it.
2178 if (packageExternalStorageType != StorageEnums.UNKNOWN) {
2179 FrameworkStatsLog.write(
2180 FrameworkStatsLog.APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED,
2181 packageExternalStorageType, res.pkg.getPackageName());
2184 if (DEBUG_INSTALL) {
2185 Slog.i(TAG, "upgrading pkg " + res.pkg + " is external");
2187 final int[] uidArray = new int[]{res.pkg.getUid()};
2188 ArrayList<String> pkgList = new ArrayList<>(1);
2189 pkgList.add(packageName);
2190 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2192 } else if (!ArrayUtils.isEmpty(res.libraryConsumers)) { // if static shared lib
2193 for (int i = 0; i < res.libraryConsumers.size(); i++) {
2194 AndroidPackage pkg = res.libraryConsumers.get(i);
2195 // send broadcast that all consumers of the static shared library have changed
2196 sendPackageChangedBroadcast(pkg.getPackageName(), false /* dontKillApp */,
2197 new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
2198 pkg.getUid(), null);
2202 // Work that needs to happen on first install within each user
2203 if (firstUserIds != null && firstUserIds.length > 0) {
2204 for (int userId : firstUserIds) {
2205 // If this app is a browser and it's newly-installed for some
2206 // users, clear any default-browser state in those users. The
2207 // app's nature doesn't depend on the user, so we can just check
2208 // its browser nature in any user and generalize.
2209 if (packageIsBrowser(packageName, userId)) {
2210 // If this browser is restored from user's backup, do not clear
2211 // default-browser state for this user
2212 synchronized (mLock) {
2213 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
2214 if (pkgSetting.getInstallReason(userId)
2215 != PackageManager.INSTALL_REASON_DEVICE_RESTORE) {
2216 mPermissionManager.setDefaultBrowser(null, true, true, userId);
2221 // We may also need to apply pending (restored) runtime permission grants
2222 // within these users.
2223 mPermissionManager.restoreDelayedRuntimePermissions(packageName,
2224 UserHandle.of(userId));
2226 // Persistent preferred activity might have came into effect due to this
2228 updateDefaultHomeNotLocked(userId);
2232 if (allNewUsers && !update) {
2233 notifyPackageAdded(packageName, res.uid);
2235 notifyPackageChanged(packageName, res.uid);
2238 // Log current value of "unknown sources" setting
2239 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2240 getUnknownSourcesSettings());
2242 // Remove the replaced package's older resources safely now
2243 InstallArgs args = res.removedInfo != null ? res.removedInfo.args : null;
2246 // If we didn't kill the app, defer the deletion of code/resource files, since
2247 // they may still be in use by the running application. This mitigates problems
2248 // in cases where resources or code is loaded by a new Activity before
2249 // ApplicationInfo changes have propagated to all application threads.
2250 scheduleDeferredNoKillPostDelete(args);
2252 synchronized (mInstallLock) {
2253 args.doPostDeleteLI(true);
2257 // Force a gc to clear up things. Ask for a background one, it's fine to go on
2258 // and not block here.
2259 VMRuntime.getRuntime().requestConcurrentGC();
2262 // Notify DexManager that the package was installed for new users.
2263 // The updated users should already be indexed and the package code paths
2264 // should not change.
2265 // Don't notify the manager for ephemeral apps as they are not expected to
2266 // survive long enough to benefit of background optimizations.
2267 for (int userId : firstUserIds) {
2268 PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2269 // There's a race currently where some install events may interleave with an
2270 // uninstall. This can lead to package info being null (b/36642664).
2272 mDexManager.notifyPackageInstalled(info, userId);
2277 final boolean deferInstallObserver = succeeded && update && !killApp;
2278 if (deferInstallObserver) {
2279 scheduleDeferredNoKillInstallObserver(res, installObserver);
2281 notifyInstallObserver(res, installObserver);
2286 public void notifyPackagesReplacedReceived(String[] packages) {
2287 final int callingUid = Binder.getCallingUid();
2288 final int callingUserId = UserHandle.getUserId(callingUid);
2290 for (String packageName : packages) {
2291 PackageSetting setting = mSettings.mPackages.get(packageName);
2293 && shouldFilterApplicationLocked(setting, callingUid, callingUserId)) {
2294 notifyInstallObserver(packageName);
2299 private void notifyInstallObserver(String packageName) {
2300 Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
2301 mNoKillInstallObservers.remove(packageName);
2304 notifyInstallObserver(pair.first, pair.second);
2308 private void notifyInstallObserver(PackageInstalledInfo info,
2309 IPackageInstallObserver2 installObserver) {
2310 if (installObserver != null) {
2312 Bundle extras = extrasForInstallResult(info);
2313 installObserver.onPackageInstalled(info.name, info.returnCode,
2314 info.returnMsg, extras);
2315 } catch (RemoteException e) {
2316 Slog.i(TAG, "Observer no longer exists.");
2321 private void scheduleDeferredNoKillPostDelete(InstallArgs args) {
2322 Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_POST_DELETE, args);
2323 mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_POST_DELETE_DELAY_MS);
2326 private void scheduleDeferredNoKillInstallObserver(PackageInstalledInfo info,
2327 IPackageInstallObserver2 observer) {
2328 String packageName = info.pkg.getPackageName();
2329 mNoKillInstallObservers.put(packageName, Pair.create(info, observer));
2330 Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_INSTALL_OBSERVER, packageName);
2331 mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS);
2335 * Gets the type of the external storage a package is installed on.
2336 * @param packageVolume The storage volume of the package.
2337 * @param packageIsExternal true if the package is currently installed on
2338 * external/removable/unprotected storage.
2339 * @return {@link StorageEnums#UNKNOWN} if the package is not stored externally or the
2340 * corresponding {@link StorageEnums} storage type value if it is.
2341 * corresponding {@link StorageEnums} storage type value if it is.
2343 private static int getPackageExternalStorageType(VolumeInfo packageVolume,
2344 boolean packageIsExternal) {
2345 if (packageVolume != null) {
2346 DiskInfo disk = packageVolume.getDisk();
2349 return StorageEnums.SD_CARD;
2352 return StorageEnums.USB;
2354 if (packageIsExternal) {
2355 return StorageEnums.OTHER;
2359 return StorageEnums.UNKNOWN;
2362 private StorageEventListener mStorageListener = new StorageEventListener() {
2364 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2365 if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2366 if (vol.state == VolumeInfo.STATE_MOUNTED) {
2367 final String volumeUuid = vol.getFsUuid();
2369 // Clean up any users or apps that were removed or recreated
2370 // while this volume was missing
2371 mUserManager.reconcileUsers(volumeUuid);
2372 reconcileApps(volumeUuid);
2374 // Clean up any install sessions that expired or were
2375 // cancelled while this volume was missing
2376 mInstallerService.onPrivateVolumeMounted(volumeUuid);
2378 loadPrivatePackages(vol);
2380 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2381 unloadPrivatePackages(vol);
2387 public void onVolumeForgotten(String fsUuid) {
2388 if (TextUtils.isEmpty(fsUuid)) {
2389 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2393 // Remove any apps installed on the forgotten volume
2394 synchronized (mLock) {
2395 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2396 for (PackageSetting ps : packages) {
2397 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2398 deletePackageVersioned(new VersionedPackage(ps.name,
2399 PackageManager.VERSION_CODE_HIGHEST),
2400 new LegacyPackageDeleteObserver(null).getBinder(),
2401 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2402 // Try very hard to release any references to this package
2403 // so we don't risk the system server being killed due to
2405 AttributeCache.instance().removePackage(ps.name);
2408 mSettings.onVolumeForgotten(fsUuid);
2409 mSettings.writeLPr();
2414 Bundle extrasForInstallResult(PackageInstalledInfo res) {
2415 Bundle extras = null;
2416 switch (res.returnCode) {
2417 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2418 extras = new Bundle();
2419 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2420 res.origPermission);
2421 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2425 case PackageManager.INSTALL_SUCCEEDED: {
2426 extras = new Bundle();
2427 extras.putBoolean(Intent.EXTRA_REPLACING,
2428 res.removedInfo != null && res.removedInfo.removedPackage != null);
2435 void scheduleWriteSettingsLocked() {
2436 // We normally invalidate when we write settings, but in cases where we delay and
2437 // coalesce settings writes, this strategy would have us invalidate the cache too late.
2438 // Invalidating on schedule addresses this problem.
2439 PackageManager.invalidatePackageInfoCache();
2440 if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2441 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2445 void scheduleWritePackageListLocked(int userId) {
2446 PackageManager.invalidatePackageInfoCache();
2447 if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2448 Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2450 mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2454 void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2455 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2456 scheduleWritePackageRestrictionsLocked(userId);
2459 void scheduleWritePackageRestrictionsLocked(int userId) {
2460 PackageManager.invalidatePackageInfoCache();
2461 final int[] userIds = (userId == UserHandle.USER_ALL)
2462 ? mUserManager.getUserIds() : new int[]{userId};
2463 for (int nextUserId : userIds) {
2464 if (!mUserManager.exists(nextUserId)) return;
2466 mDirtyUsers.add(nextUserId);
2467 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2468 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2473 public static PackageManagerService main(Context context, Installer installer,
2474 boolean factoryTest, boolean onlyCore) {
2475 // Self-check for initial settings.
2476 PackageManagerServiceCompilerMapping.checkProperties();
2477 final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
2478 Trace.TRACE_TAG_PACKAGE_MANAGER);
2479 t.traceBegin("create package manager");
2480 final Object lock = new Object();
2481 final Object installLock = new Object();
2483 Injector injector = new Injector(
2484 context, lock, installer, installLock, new PackageAbiHelperImpl(),
2486 new ComponentResolver(i.getUserManagerService(), pm.mPmInternal, lock),
2488 PermissionManagerService.create(context, lock),
2490 new UserManagerService(context, pm,
2491 new UserDataPreparer(installer, installLock, context, onlyCore),
2494 new Settings(Environment.getDataDirectory(),
2495 i.getPermissionManagerServiceInternal().getPermissionSettings(),
2497 new Injector.LocalServicesProducer<>(ActivityTaskManagerInternal.class),
2498 new Injector.LocalServicesProducer<>(DeviceIdleInternal.class),
2499 new Injector.LocalServicesProducer<>(StorageManagerInternal.class),
2500 new Injector.LocalServicesProducer<>(NetworkPolicyManagerInternal.class),
2501 new Injector.LocalServicesProducer<>(PermissionPolicyInternal.class),
2502 new Injector.LocalServicesProducer<>(DeviceStorageMonitorInternal.class),
2503 new Injector.SystemServiceProducer<>(DisplayManager.class),
2504 new Injector.SystemServiceProducer<>(StorageManager.class),
2505 new Injector.SystemServiceProducer<>(AppOpsManager.class),
2506 (i, pm) -> AppsFilter.create(pm.mPmInternal, i),
2507 (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"));
2509 PackageManagerService m = new PackageManagerService(injector, factoryTest, onlyCore);
2510 t.traceEnd(); // "create package manager"
2512 injector.getCompatibility().registerListener(SELinuxMMAC.SELINUX_LATEST_CHANGES,
2514 synchronized (m.mInstallLock) {
2515 final AndroidPackage pkg;
2516 final PackageSetting ps;
2517 final SharedUserSetting sharedUser;
2518 final String oldSeInfo;
2519 synchronized (m.mLock) {
2520 ps = m.mSettings.getPackageLPr(packageName);
2522 Slog.e(TAG, "Failed to find package setting " + packageName);
2526 sharedUser = ps.getSharedUser();
2527 oldSeInfo = AndroidPackageUtils.getSeInfo(pkg, ps);
2531 Slog.e(TAG, "Failed to find package " + packageName);
2534 final String newSeInfo = SELinuxMMAC.getSeInfo(pkg, sharedUser,
2535 m.mInjector.getCompatibility());
2537 if (!newSeInfo.equals(oldSeInfo)) {
2538 Slog.i(TAG, "Updating seInfo for package " + packageName + " from: "
2539 + oldSeInfo + " to: " + newSeInfo);
2540 ps.getPkgState().setOverrideSeInfo(newSeInfo);
2541 m.prepareAppDataAfterInstallLIF(pkg);
2546 m.installWhitelistedSystemPackages();
2547 ServiceManager.addService("package", m);
2548 final PackageManagerNative pmn = m.new PackageManagerNative();
2549 ServiceManager.addService("package_native", pmn);
2553 /** Install/uninstall system packages for all users based on their user-type, as applicable. */
2554 private void installWhitelistedSystemPackages() {
2555 synchronized (mLock) {
2556 final boolean scheduleWrite = mUserManager.installWhitelistedSystemPackages(
2557 isFirstBoot(), isDeviceUpgrading());
2558 if (scheduleWrite) {
2559 scheduleWritePackageRestrictionsLocked(UserHandle.USER_ALL);
2564 private static void getDefaultDisplayMetrics(
2565 DisplayManager displayManager, DisplayMetrics metrics) {
2566 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2570 * Requests that files preopted on a secondary system partition be copied to the data partition
2571 * if possible. Note that the actual copying of the files is accomplished by init for security
2572 * reasons. This simply requests that the copy takes place and awaits confirmation of its
2573 * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2575 private static void requestCopyPreoptedFiles() {
2576 final int WAIT_TIME_MS = 100;
2577 final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2578 if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2579 SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2580 // We will wait for up to 100 seconds.
2581 final long timeStart = SystemClock.uptimeMillis();
2582 final long timeEnd = timeStart + 100 * 1000;
2583 long timeNow = timeStart;
2584 while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2586 Thread.sleep(WAIT_TIME_MS);
2587 } catch (InterruptedException e) {
2590 timeNow = SystemClock.uptimeMillis();
2591 if (timeNow > timeEnd) {
2592 SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2593 Slog.wtf(TAG, "cppreopt did not finish!");
2598 Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2603 public static class ScanPartition extends SystemPartition {
2605 public final int scanFlag;
2607 public ScanPartition(@NonNull SystemPartition partition) {
2609 scanFlag = scanFlagForPartition(partition);
2613 * Creates a partition containing the same folders as the original partition but with a
2614 * different root folder. The new partition will include the scan flags of the original
2615 * partition along with any specified additional scan flags.
2617 public ScanPartition(@NonNull File folder, @NonNull ScanPartition original,
2618 @ScanFlags int additionalScanFlag) {
2619 super(folder, original);
2620 this.scanFlag = original.scanFlag | additionalScanFlag;
2623 private static int scanFlagForPartition(PackagePartitions.SystemPartition partition) {
2624 switch (partition.type) {
2625 case PackagePartitions.PARTITION_SYSTEM:
2627 case PackagePartitions.PARTITION_VENDOR:
2628 return SCAN_AS_VENDOR;
2629 case PackagePartitions.PARTITION_ODM:
2631 case PackagePartitions.PARTITION_OEM:
2633 case PackagePartitions.PARTITION_PRODUCT:
2634 return SCAN_AS_PRODUCT;
2635 case PackagePartitions.PARTITION_SYSTEM_EXT:
2636 return SCAN_AS_SYSTEM_EXT;
2638 throw new IllegalStateException("Unable to determine scan flag for "
2639 + partition.folder);
2644 public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) {
2645 PackageManager.invalidatePackageInfoCache();
2646 PackageManager.disableApplicationInfoCache();
2647 PackageManager.disablePackageInfoCache();
2649 final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
2650 Trace.TRACE_TAG_PACKAGE_MANAGER);
2651 mInjector = injector;
2652 mInjector.bootstrap(this);
2653 mLock = injector.getLock();
2654 mInstallLock = injector.getInstallLock();
2655 LockGuard.installLock(mLock, LockGuard.INDEX_PACKAGES);
2656 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2657 SystemClock.uptimeMillis());
2659 if (mSdkVersion <= 0) {
2660 Slog.w(TAG, "**** ro.build.version.sdk not set!");
2663 mContext = injector.getContext();
2664 mFactoryTest = factoryTest;
2665 mOnlyCore = onlyCore;
2666 mMetrics = new DisplayMetrics();
2667 mInstaller = injector.getInstaller();
2669 // Create sub-components that provide services / data. Order here is important.
2670 t.traceBegin("createSubComponents");
2672 // Expose private service for system components to use.
2673 mPmInternal = new PackageManagerInternalImpl();
2674 LocalServices.addService(PackageManagerInternal.class, mPmInternal);
2675 mUserManager = injector.getUserManagerService();
2676 mComponentResolver = injector.getComponentResolver();
2677 mPermissionManager = injector.getPermissionManagerServiceInternal();
2678 mSettings = injector.getSettings();
2679 mPermissionManagerService = (IPermissionManager) ServiceManager.getService("permissionmgr");
2680 mIncrementalManager =
2681 (IncrementalManager) mContext.getSystemService(Context.INCREMENTAL_SERVICE);
2683 // CHECKSTYLE:ON IndentationCheck
2686 t.traceBegin("addSharedUsers");
2687 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2688 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2689 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2690 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2691 mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2692 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2693 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2694 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2695 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2696 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2697 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2698 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2699 mSettings.addSharedUserLPw("android.uid.se", SE_UID,
2700 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2701 mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID,
2702 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2705 String separateProcesses = SystemProperties.get("debug.separate_processes");
2706 if (separateProcesses != null && separateProcesses.length() > 0) {
2707 if ("*".equals(separateProcesses)) {
2708 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2709 mSeparateProcesses = null;
2710 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2713 mSeparateProcesses = separateProcesses.split(",");
2714 Slog.w(TAG, "Running with debug.separate_processes: "
2715 + separateProcesses);
2719 mSeparateProcesses = null;
2722 mPackageDexOptimizer = new PackageDexOptimizer(mInstaller, mInstallLock, mContext,
2725 new DexManager(mContext, this, mPackageDexOptimizer, mInstaller, mInstallLock);
2726 mArtManagerService = new ArtManagerService(mContext, this, mInstaller, mInstallLock);
2727 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2729 mViewCompiler = new ViewCompiler(mInstallLock, mInstaller);
2731 getDefaultDisplayMetrics(mInjector.getDisplayManager(), mMetrics);
2733 t.traceBegin("get system config");
2734 SystemConfig systemConfig = SystemConfig.getInstance();
2735 mAvailableFeatures = systemConfig.getAvailableFeatures();
2736 ApplicationPackageManager.invalidateHasSystemFeatureCache();
2739 mProtectedPackages = new ProtectedPackages(mContext);
2741 mApexManager = ApexManager.getInstance();
2742 mAppsFilter = mInjector.getAppsFilter();
2744 mDirsToScanAsSystem = new ArrayList<>();
2745 mDirsToScanAsSystem.addAll(SYSTEM_PARTITIONS);
2746 mDirsToScanAsSystem.addAll(mApexManager.getActiveApexInfos().stream()
2747 .map(PackageManagerService::resolveApexToScanPartition)
2748 .filter(Objects::nonNull).collect(Collectors.toList()));
2750 "Directories scanned as system partitions: [" + mDirsToScanAsSystem.stream().map(
2751 d -> (d.folder.getAbsolutePath() + ":" + d.scanFlag))
2752 .collect(Collectors.joining(",")) + "]");
2754 // CHECKSTYLE:OFF IndentationCheck
2755 synchronized (mInstallLock) {
2757 synchronized (mLock) {
2758 mHandlerThread = new ServiceThread(TAG,
2759 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2760 mHandlerThread.start();
2761 mHandler = new PackageHandler(mHandlerThread.getLooper());
2762 mProcessLoggingHandler = new ProcessLoggingHandler();
2763 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2764 mInstantAppRegistry = new InstantAppRegistry(this);
2766 ArrayMap<String, SystemConfig.SharedLibraryEntry> libConfig
2767 = systemConfig.getSharedLibraries();
2768 final int builtInLibCount = libConfig.size();
2769 for (int i = 0; i < builtInLibCount; i++) {
2770 String name = libConfig.keyAt(i);
2771 SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
2772 addBuiltInSharedLibraryLocked(entry.filename, name);
2775 // Now that we have added all the libraries, iterate again to add dependency
2776 // information IFF their dependencies are added.
2777 long undefinedVersion = SharedLibraryInfo.VERSION_UNDEFINED;
2778 for (int i = 0; i < builtInLibCount; i++) {
2779 String name = libConfig.keyAt(i);
2780 SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
2781 final int dependencyCount = entry.dependencies.length;
2782 for (int j = 0; j < dependencyCount; j++) {
2783 final SharedLibraryInfo dependency =
2784 getSharedLibraryInfoLPr(entry.dependencies[j], undefinedVersion);
2785 if (dependency != null) {
2786 getSharedLibraryInfoLPr(name, undefinedVersion).addDependency(dependency);
2791 SELinuxMMAC.readInstallPolicy();
2793 t.traceBegin("loadFallbacks");
2794 FallbackCategoryProvider.loadFallbacks();
2797 t.traceBegin("read user settings");
2798 mFirstBoot = !mSettings.readLPw(mUserManager.getUsers(false));
2801 // Clean up orphaned packages for which the code path doesn't exist
2802 // and they are an update to a system app - caused by bug/32321269
2803 final int packageSettingCount = mSettings.mPackages.size();
2804 for (int i = packageSettingCount - 1; i >= 0; i--) {
2805 PackageSetting ps = mSettings.mPackages.valueAt(i);
2806 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2807 && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2808 mSettings.mPackages.removeAt(i);
2809 mSettings.enableSystemPackageLPw(ps.name);
2813 if (!mOnlyCore && mFirstBoot) {
2814 requestCopyPreoptedFiles();
2817 String customResolverActivityName = Resources.getSystem().getString(
2818 R.string.config_customResolverActivity);
2819 if (!TextUtils.isEmpty(customResolverActivityName)) {
2820 mCustomResolverComponentName = ComponentName.unflattenFromString(
2821 customResolverActivityName);
2824 long startTime = SystemClock.uptimeMillis();
2826 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2829 final String bootClassPath = System.getenv("BOOTCLASSPATH");
2830 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2832 if (bootClassPath == null) {
2833 Slog.w(TAG, "No BOOTCLASSPATH found!");
2836 if (systemServerClassPath == null) {
2837 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2840 File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2842 final VersionInfo ver = mSettings.getInternalVersion();
2843 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2845 logCriticalInfo(Log.INFO,
2846 "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2849 // when upgrading from pre-M, promote system app permissions from install to runtime
2850 mPromoteSystemApps =
2851 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2853 // When upgrading from pre-N, we need to handle package extraction like first boot,
2854 // as there is no profiling data available.
2855 mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2857 mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2858 mIsPreQUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.Q;
2860 // save off the names of pre-existing system packages prior to scanning; we don't
2861 // want to automatically grant runtime permissions for new system apps
2862 if (mPromoteSystemApps) {
2863 for (PackageSetting ps : mSettings.mPackages.values()) {
2864 if (isSystemApp(ps)) {
2865 mExistingSystemPackages.add(ps.name);
2870 mCacheDir = preparePackageParserCache();
2872 // Set flag to monitor and not change apk file paths when
2873 // scanning install directories.
2874 int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2876 if (mIsUpgrade || mFirstBoot) {
2877 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2880 final int systemParseFlags = mDefParseFlags | PackageParser.PARSE_IS_SYSTEM_DIR;
2881 final int systemScanFlags = scanFlags | SCAN_AS_SYSTEM;
2883 PackageParser2 packageParser = new PackageParser2(mSeparateProcesses, mOnlyCore,
2884 mMetrics, mCacheDir, mPackageParserCallback);
2886 ExecutorService executorService = ParallelPackageParser.makeExecutorService();
2887 // Collect vendor/product/system_ext overlay packages. (Do this before scanning
2889 // For security and version matching reason, only consider overlay packages if they
2890 // reside in the right directory.
2891 for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
2892 final ScanPartition partition = mDirsToScanAsSystem.get(i);
2893 if (partition.getOverlayFolder() == null) {
2896 scanDirTracedLI(partition.getOverlayFolder(), systemParseFlags,
2897 systemScanFlags | partition.scanFlag, 0,
2898 packageParser, executorService);
2901 scanDirTracedLI(frameworkDir, systemParseFlags,
2902 systemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED, 0,
2903 packageParser, executorService);
2904 if (!mPackages.containsKey("android")) {
2905 throw new IllegalStateException(
2906 "Failed to load frameworks package; check log for warnings");
2908 for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
2909 final ScanPartition partition = mDirsToScanAsSystem.get(i);
2910 if (partition.getPrivAppFolder() != null) {
2911 scanDirTracedLI(partition.getPrivAppFolder(), systemParseFlags,
2912 systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0,
2913 packageParser, executorService);
2915 scanDirTracedLI(partition.getAppFolder(), systemParseFlags,
2916 systemScanFlags | partition.scanFlag, 0,
2917 packageParser, executorService);
2920 // Parse overlay configuration files to set default enable state, mutability, and
2921 // priority of system overlays.
2922 mOverlayConfig = OverlayConfig.initializeSystemInstance(
2923 consumer -> mPmInternal.forEachPackage(
2924 pkg -> consumer.accept(pkg, pkg.isSystem())));
2926 // Prune any system packages that no longer exist.
2927 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2928 // Stub packages must either be replaced with full versions in the /data
2929 // partition or be disabled.
2930 final List<String> stubSystemApps = new ArrayList<>();
2932 // do this first before mucking with mPackages for the "expecting better" case
2933 final Iterator<AndroidPackage> pkgIterator = mPackages.values().iterator();
2934 while (pkgIterator.hasNext()) {
2935 final AndroidPackage pkg = pkgIterator.next();
2937 stubSystemApps.add(pkg.getPackageName());
2941 final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2942 while (psit.hasNext()) {
2943 PackageSetting ps = psit.next();
2946 * If this is not a system app, it can't be a
2947 * disable system app.
2949 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2954 * If the package is scanned, it's not erased.
2956 final AndroidPackage scannedPkg = mPackages.get(ps.name);
2957 if (scannedPkg != null) {
2959 * If the system app is both scanned and in the
2960 * disabled packages list, then it must have been
2961 * added via OTA. Remove it from the currently
2962 * scanned package so the previously user-installed
2963 * application can be scanned.
2965 if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2966 logCriticalInfo(Log.WARN,
2967 "Expecting better updated system app for " + ps.name
2968 + "; removing system app. Last known"
2969 + " codePath=" + ps.codePathString
2970 + ", versionCode=" + ps.versionCode
2971 + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
2972 removePackageLI(scannedPkg, true);
2973 mExpectingBetter.put(ps.name, ps.codePath);
2979 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2981 logCriticalInfo(Log.WARN, "System package " + ps.name
2982 + " no longer exists; it's data will be wiped");
2983 // Actual deletion of code and data will be handled by later
2984 // reconciliation step
2986 // we still have a disabled system package, but, it still might have
2987 // been removed. check the code path still exists and check there's
2988 // still a package. the latter can happen if an OTA keeps the same
2989 // code path, but, changes the package name.
2990 final PackageSetting disabledPs =
2991 mSettings.getDisabledSystemPkgLPr(ps.name);
2992 if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2993 || disabledPs.pkg == null) {
2994 possiblyDeletedUpdatedSystemApps.add(ps.name);
2996 // We're expecting that the system app should remain disabled, but add
2997 // it to expecting better to recover in case the data version cannot
2999 mExpectingBetter.put(disabledPs.name, disabledPs.codePath);
3005 final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
3007 // Remove any shared userIDs that have no associated packages
3008 mSettings.pruneSharedUsersLPw();
3009 final long systemScanTime = SystemClock.uptimeMillis() - startTime;
3010 final int systemPackagesCount = mPackages.size();
3011 Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
3012 + " ms, packageCount: " + systemPackagesCount
3013 + " , timePerPackage: "
3014 + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
3015 + " , cached: " + cachedSystemApps);
3016 if (mIsUpgrade && systemPackagesCount > 0) {
3017 //CHECKSTYLE:OFF IndentationCheck
3018 FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
3019 BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME,
3020 systemScanTime / systemPackagesCount);
3021 //CHECKSTYLE:ON IndentationCheck
3024 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
3025 SystemClock.uptimeMillis());
3026 scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0,
3027 packageParser, executorService);
3031 List<Runnable> unfinishedTasks = executorService.shutdownNow();
3032 if (!unfinishedTasks.isEmpty()) {
3033 throw new IllegalStateException("Not all tasks finished before calling close: "
3038 // Remove disable package settings for updated system apps that were
3039 // removed via an OTA. If the update is no longer present, remove the
3040 // app completely. Otherwise, revoke their system privileges.
3041 for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
3042 final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
3043 final AndroidPackage pkg = mPackages.get(packageName);
3046 // remove from the disabled system list; do this first so any future
3047 // scans of this package are performed without this state
3048 mSettings.removeDisabledSystemPackageLPw(packageName);
3051 // should have found an update, but, we didn't; remove everything
3052 msg = "Updated system package " + packageName
3053 + " no longer exists; removing its data";
3054 // Actual deletion of code and data will be handled by later
3055 // reconciliation step
3057 // found an update; revoke system privileges
3058 msg = "Updated system package " + packageName
3059 + " no longer exists; rescanning package on data";
3061 // NOTE: We don't do anything special if a stub is removed from the
3062 // system image. But, if we were [like removing the uncompressed
3063 // version from the /data partition], this is where it'd be done.
3065 // remove the package from the system and re-scan it without any
3066 // special privileges
3067 removePackageLI(pkg, true);
3069 final File codePath = new File(pkg.getCodePath());
3070 scanPackageTracedLI(codePath, 0, scanFlags, 0, null);
3071 } catch (PackageManagerException e) {
3072 Slog.e(TAG, "Failed to parse updated, ex-system package: "
3077 // one final check. if we still have a package setting [ie. it was
3078 // previously scanned and known to the system], but, we don't have
3079 // a package [ie. there was an error scanning it from the /data
3080 // partition], completely remove the package data.
3081 final PackageSetting ps = mSettings.mPackages.get(packageName);
3082 if (ps != null && mPackages.get(packageName) == null) {
3083 removePackageDataLIF(ps, null, null, 0, false);
3086 logCriticalInfo(Log.WARN, msg);
3090 * Make sure all system apps that we expected to appear on
3091 * the userdata partition actually showed up. If they never
3092 * appeared, crawl back and revive the system version.
3094 for (int i = 0; i < mExpectingBetter.size(); i++) {
3095 final String packageName = mExpectingBetter.keyAt(i);
3096 if (!mPackages.containsKey(packageName)) {
3097 final File scanFile = mExpectingBetter.valueAt(i);
3099 logCriticalInfo(Log.WARN, "Expected better " + packageName
3100 + " but never showed up; reverting to system");
3102 @ParseFlags int reparseFlags = 0;
3103 @ScanFlags int rescanFlags = 0;
3104 for (int i1 = 0, size = mDirsToScanAsSystem.size(); i1 < size; i1++) {
3105 final ScanPartition partition = mDirsToScanAsSystem.get(i1);
3106 if (partition.containsPrivApp(scanFile)) {
3107 reparseFlags = systemParseFlags;
3108 rescanFlags = systemScanFlags | SCAN_AS_PRIVILEGED
3109 | partition.scanFlag;
3112 if (partition.containsApp(scanFile)) {
3113 reparseFlags = systemParseFlags;
3114 rescanFlags = systemScanFlags | partition.scanFlag;
3118 if (rescanFlags == 0) {
3119 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
3122 mSettings.enableSystemPackageLPw(packageName);
3125 scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
3126 } catch (PackageManagerException e) {
3127 Slog.e(TAG, "Failed to parse original system package: "
3133 // Uncompress and install any stubbed system applications.
3134 // This must be done last to ensure all stubs are replaced or disabled.
3135 installSystemStubPackages(stubSystemApps, scanFlags);
3137 final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
3140 final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
3141 final int dataPackagesCount = mPackages.size() - systemPackagesCount;
3142 Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
3143 + " ms, packageCount: " + dataPackagesCount
3144 + " , timePerPackage: "
3145 + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
3146 + " , cached: " + cachedNonSystemApps);
3147 if (mIsUpgrade && dataPackagesCount > 0) {
3148 //CHECKSTYLE:OFF IndentationCheck
3149 FrameworkStatsLog.write(
3150 FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
3151 BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME,
3152 dataScanTime / dataPackagesCount);
3153 //CHECKSTYLE:OFF IndentationCheck
3156 mExpectingBetter.clear();
3158 // Resolve the storage manager.
3159 mStorageManagerPackage = getStorageManagerPackageName();
3161 // Resolve protected action filters. Only the setup wizard is allowed to
3162 // have a high priority filter for these actions.
3163 mSetupWizardPackage = getSetupWizardPackageNameImpl();
3164 mComponentResolver.fixProtectedFilterPriorities();
3166 mDefaultTextClassifierPackage = getDefaultTextClassifierPackageName();
3167 mSystemTextClassifierPackageName = getSystemTextClassifierPackageName();
3168 mWellbeingPackage = getWellbeingPackageName();
3169 mDocumenterPackage = getDocumenterPackageName();
3170 mConfiguratorPackage = getDeviceConfiguratorPackageName();
3171 mAppPredictionServicePackage = getAppPredictionServicePackageName();
3172 mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
3173 mTelephonyPackages = getTelephonyPackageNames();
3174 mRetailDemoPackage = getRetailDemoPackageName();
3176 // Now that we know all of the shared libraries, update all clients to have
3177 // the correct library paths.
3178 updateAllSharedLibrariesLocked(null, null, Collections.unmodifiableMap(mPackages));
3180 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
3181 // NOTE: We ignore potential failures here during a system scan (like
3182 // the rest of the commands above) because there's precious little we
3183 // can do about it. A settings error is reported, though.
3184 final List<String> changedAbiCodePath =
3185 applyAdjustedAbiToSharedUser(setting, null /*scannedPackage*/,
3186 mInjector.getAbiHelper().getAdjustedAbiForSharedUser(
3187 setting.packages, null /*scannedPackage*/));
3188 if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
3189 for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
3190 final String codePathString = changedAbiCodePath.get(i);
3192 mInstaller.rmdex(codePathString,
3193 getDexCodeInstructionSet(getPreferredInstructionSet()));
3194 } catch (InstallerException ignored) {
3198 // Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
3200 setting.fixSeInfoLocked();
3201 setting.updateProcesses();
3204 // Now that we know all the packages we are keeping,
3205 // read and update their last usage times.
3206 mPackageUsage.read(mSettings.mPackages);
3207 mCompilerStats.read();
3209 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
3210 SystemClock.uptimeMillis());
3211 Slog.i(TAG, "Time to scan packages: "
3212 + ((SystemClock.uptimeMillis()-startTime)/1000f)
3215 // If the platform SDK has changed since the last time we booted,
3216 // we need to re-grant app permission to catch any new ones that
3217 // appear. This is really a hack, and means that apps can in some
3218 // cases get permissions that the user didn't initially explicitly
3219 // allow... it would be nice to have some better way to handle
3221 final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
3223 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
3224 + mSdkVersion + "; regranting permissions for internal storage");
3226 mPermissionManager.updateAllPermissions(
3227 StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated);
3228 ver.sdkVersion = mSdkVersion;
3230 // If this is the first boot or an update from pre-M, and it is a normal
3231 // boot, then we need to initialize the default preferred apps across
3232 // all defined users.
3233 if (!mOnlyCore && (mPromoteSystemApps || mFirstBoot)) {
3234 for (UserInfo user : mUserManager.getUsers(true)) {
3235 mSettings.applyDefaultPreferredAppsLPw(user.id);
3236 primeDomainVerificationsLPw(user.id);
3240 // Prepare storage for system user really early during boot,
3241 // since core system apps like SettingsProvider and SystemUI
3242 // can't wait for user to start
3243 final int storageFlags;
3244 if (StorageManager.isFileEncryptedNativeOrEmulated()) {
3245 storageFlags = StorageManager.FLAG_STORAGE_DE;
3247 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
3249 List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
3250 UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
3251 true /* onlyCoreApps */);
3252 mPrepareAppDataFuture = SystemServerInitThreadPool.submit(() -> {
3253 TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
3254 Trace.TRACE_TAG_PACKAGE_MANAGER);
3255 traceLog.traceBegin("AppDataFixup");
3257 mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
3258 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
3259 } catch (InstallerException e) {
3260 Slog.w(TAG, "Trouble fixing GIDs", e);
3262 traceLog.traceEnd();
3264 traceLog.traceBegin("AppDataPrepare");
3265 if (deferPackages == null || deferPackages.isEmpty()) {
3269 for (String pkgName : deferPackages) {
3270 AndroidPackage pkg = null;
3271 synchronized (mLock) {
3272 PackageSetting ps = mSettings.getPackageLPr(pkgName);
3273 if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
3278 synchronized (mInstallLock) {
3279 prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
3280 true /* maybeMigrateAppData */);
3285 traceLog.traceEnd();
3286 Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
3287 }, "prepareAppData");
3289 // If this is first boot after an OTA, and a normal boot, then
3290 // we need to clear code cache directories.
3291 // Note that we do *not* clear the application profiles. These remain valid
3292 // across OTAs and are used to drive profile verification (post OTA) and
3293 // profile compilation (without waiting to collect a fresh set of profiles).
3294 if (mIsUpgrade && !mOnlyCore) {
3295 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
3296 for (int i = 0; i < mSettings.mPackages.size(); i++) {
3297 final PackageSetting ps = mSettings.mPackages.valueAt(i);
3298 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
3299 // No apps are running this early, so no need to freeze
3300 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
3301 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
3302 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY
3303 | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
3306 ver.fingerprint = Build.FINGERPRINT;
3309 // Grandfather existing (installed before Q) non-system apps to hide
3310 // their icons in launcher.
3311 if (!mOnlyCore && mIsPreQUpgrade) {
3312 Slog.i(TAG, "Whitelisting all existing apps to hide their icons");
3313 int size = mSettings.mPackages.size();
3314 for (int i = 0; i < size; i++) {
3315 final PackageSetting ps = mSettings.mPackages.valueAt(i);
3316 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
3319 ps.disableComponentLPw(PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME,
3320 UserHandle.USER_SYSTEM);
3324 // clear only after permissions and other defaults have been updated
3325 mExistingSystemPackages.clear();
3326 mPromoteSystemApps = false;
3328 // All the changes are done during package scanning.
3329 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
3331 // can downgrade to reader
3332 t.traceBegin("write settings");
3333 mSettings.writeLPr();
3335 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3336 SystemClock.uptimeMillis());
3339 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3340 mRequiredInstallerPackage = getRequiredInstallerLPr();
3341 mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3342 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3343 if (mIntentFilterVerifierComponent != null) {
3344 mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3345 mIntentFilterVerifierComponent);
3347 mIntentFilterVerifier = null;
3349 mServicesExtensionPackageName = getRequiredServicesExtensionPackageLPr();
3350 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3351 PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3352 SharedLibraryInfo.VERSION_UNDEFINED);
3354 mRequiredVerifierPackage = null;
3355 mRequiredInstallerPackage = null;
3356 mRequiredUninstallerPackage = null;
3357 mIntentFilterVerifierComponent = null;
3358 mIntentFilterVerifier = null;
3359 mServicesExtensionPackageName = null;
3360 mSharedSystemSharedLibraryPackageName = null;
3363 // PermissionController hosts default permission granting and role management, so it's a
3364 // critical part of the core system.
3365 mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr();
3367 // Initialize InstantAppRegistry's Instant App list for all users.
3368 final int[] userIds = UserManagerService.getInstance().getUserIds();
3369 for (AndroidPackage pkg : mPackages.values()) {
3370 if (pkg.isSystem()) {
3373 for (int userId : userIds) {
3374 final PackageSetting ps = getPackageSetting(pkg.getPackageName());
3375 if (ps == null || !ps.getInstantApp(userId) || !ps.getInstalled(userId)) {
3378 mInstantAppRegistry.addInstantAppLPw(userId, ps.appId);
3382 mInstallerService = new PackageInstallerService(mContext, this);
3383 final Pair<ComponentName, String> instantAppResolverComponent =
3384 getInstantAppResolverLPr();
3385 if (instantAppResolverComponent != null) {
3386 if (DEBUG_INSTANT) {
3387 Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3389 mInstantAppResolverConnection = new InstantAppResolverConnection(
3390 mContext, instantAppResolverComponent.first,
3391 instantAppResolverComponent.second);
3392 mInstantAppResolverSettingsComponent =
3393 getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3395 mInstantAppResolverConnection = null;
3396 mInstantAppResolverSettingsComponent = null;
3398 updateInstantAppInstallerLocked(null);
3400 // Read and update the usage of dex files.
3401 // Do this at the end of PM init so that all the packages have their
3402 // data directory reconciled.
3403 // At this point we know the code paths of the packages, so we can validate
3404 // the disk file and build the internal cache.
3405 // The usage file is expected to be small so loading and verifying it
3406 // should take a fairly small time compare to the other activities (e.g. package
3408 final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3409 for (int userId : userIds) {
3410 userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3412 mDexManager.load(userPackages);
3414 FrameworkStatsLog.write(
3415 FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
3416 BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_INIT_TIME,
3417 SystemClock.uptimeMillis() - startTime);
3419 } // synchronized (mLock)
3420 } // synchronized (mInstallLock)
3421 // CHECKSTYLE:ON IndentationCheck
3423 mModuleInfoProvider = new ModuleInfoProvider(mContext, this);
3425 // Now after opening every single application zip, make sure they
3426 // are all flushed. Not really needed, but keeps things nice and
3429 Runtime.getRuntime().gc();
3432 // The initial scanning above does many calls into installd while
3433 // holding the mPackages lock, but we're mostly interested in yelling
3434 // once we have a booted system.
3435 mInstaller.setWarnIfHeld(mLock);
3437 PackageParser.readConfigUseRoundIcon(mContext.getResources());
3439 mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);
3443 * Uncompress and install stub applications.
3444 * <p>In order to save space on the system partition, some applications are shipped in a
3445 * compressed form. In addition the compressed bits for the full application, the
3446 * system image contains a tiny stub comprised of only the Android manifest.
3447 * <p>During the first boot, attempt to uncompress and install the full application. If
3448 * the application can't be installed for any reason, disable the stub and prevent
3449 * uncompressing the full application during future boots.
3450 * <p>In order to forcefully attempt an installation of a full application, go to app
3451 * settings and enable the application.
3453 private void installSystemStubPackages(@NonNull List<String> systemStubPackageNames,
3454 @ScanFlags int scanFlags) {
3455 for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) {
3456 final String packageName = systemStubPackageNames.get(i);
3457 // skip if the system package is already disabled
3458 if (mSettings.isDisabledSystemPackageLPr(packageName)) {
3459 systemStubPackageNames.remove(i);
3462 // skip if the package isn't installed (?!); this should never happen
3463 final AndroidPackage pkg = mPackages.get(packageName);
3465 systemStubPackageNames.remove(i);
3468 // skip if the package has been disabled by the user
3469 final PackageSetting ps = mSettings.mPackages.get(packageName);
3471 final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3472 if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3473 systemStubPackageNames.remove(i);
3478 // install the package to replace the stub on /system
3480 installStubPackageLI(pkg, 0, scanFlags);
3481 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3482 UserHandle.USER_SYSTEM, "android");
3483 systemStubPackageNames.remove(i);
3484 } catch (PackageManagerException e) {
3485 Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3488 // any failed attempt to install the package will be cleaned up later
3491 // disable any stub still left; these failed to install the full application
3492 for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) {
3493 final String pkgName = systemStubPackageNames.get(i);
3494 final PackageSetting ps = mSettings.mPackages.get(pkgName);
3495 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3496 UserHandle.USER_SYSTEM, "android");
3497 logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3502 * Extract, install and enable a stub package.
3503 * <p>If the compressed file can not be extracted / installed for any reason, the stub
3504 * APK will be installed and the package will be disabled. To recover from this situation,
3505 * the user will need to go into system settings and re-enable the package.
3507 private boolean enableCompressedPackage(AndroidPackage stubPkg,
3508 @NonNull PackageSetting stubPkgSetting) {
3509 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
3510 | PackageParser.PARSE_ENFORCE_CODE;
3511 synchronized (mInstallLock) {
3512 final AndroidPackage pkg;
3513 try (PackageFreezer freezer =
3514 freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
3515 pkg = installStubPackageLI(stubPkg, parseFlags, 0 /*scanFlags*/);
3516 synchronized (mLock) {
3517 prepareAppDataAfterInstallLIF(pkg);
3519 updateSharedLibrariesLocked(pkg, stubPkgSetting, null, null,
3520 Collections.unmodifiableMap(mPackages));
3521 } catch (PackageManagerException e) {
3522 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
3524 mPermissionManager.updatePermissions(pkg.getPackageName(), pkg);
3525 mSettings.writeLPr();
3527 } catch (PackageManagerException e) {
3528 // Whoops! Something went very wrong; roll back to the stub and disable the package
3529 try (PackageFreezer freezer =
3530 freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
3531 synchronized (mLock) {
3532 // NOTE: Ensure the system package is enabled; even for a compressed stub.
3533 // If we don't, installing the system package fails during scan
3534 enableSystemPackageLPw(stubPkg);
3536 installPackageFromSystemLIF(stubPkg.getCodePath(),
3537 null /*allUserHandles*/, null /*origUserHandles*/,
3538 null /*origPermissionsState*/, true /*writeSettings*/);
3539 } catch (PackageManagerException pme) {
3540 // Serious WTF; we have to be able to install the stub
3541 Slog.wtf(TAG, "Failed to restore system package:" + stubPkg.getPackageName(),
3544 // Disable the package; the stub by itself is not runnable
3545 synchronized (mLock) {
3546 final PackageSetting stubPs = mSettings.mPackages.get(
3547 stubPkg.getPackageName());
3548 if (stubPs != null) {
3549 stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED,
3550 UserHandle.USER_SYSTEM, "android");
3552 mSettings.writeLPr();
3557 clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
3558 | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3559 mDexManager.notifyPackageUpdated(pkg.getPackageName(),
3560 pkg.getBaseCodePath(), pkg.getSplitCodePaths());
3565 private AndroidPackage installStubPackageLI(AndroidPackage stubPkg,
3566 @ParseFlags int parseFlags, @ScanFlags int scanFlags)
3567 throws PackageManagerException {
3568 if (DEBUG_COMPRESSION) {
3569 Slog.i(TAG, "Uncompressing system stub; pkg: " + stubPkg.getPackageName());
3571 // uncompress the binary to its eventual destination on /data
3572 final File scanFile = decompressPackage(stubPkg.getPackageName(), stubPkg.getCodePath());
3573 if (scanFile == null) {
3574 throw new PackageManagerException(
3575 "Unable to decompress stub at " + stubPkg.getCodePath());
3577 synchronized (mLock) {
3578 mSettings.disableSystemPackageLPw(stubPkg.getPackageName(), true /*replaced*/);
3580 removePackageLI(stubPkg, true /*chatty*/);
3582 return scanPackageTracedLI(scanFile, parseFlags, scanFlags, 0, null);
3583 } catch (PackageManagerException e) {
3584 Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.getPackageName(),
3586 // Remove the failed install
3587 removeCodePathLI(scanFile);
3593 * Decompresses the given package on the system image onto
3594 * the /data partition.
3595 * @return The directory the package was decompressed into. Otherwise, {@code null}.
3597 private File decompressPackage(String packageName, String codePath) {
3598 final File[] compressedFiles = getCompressedFiles(codePath);
3599 if (compressedFiles == null || compressedFiles.length == 0) {
3600 if (DEBUG_COMPRESSION) {
3601 Slog.i(TAG, "No files to decompress: " + codePath);
3605 final File dstCodePath =
3606 getNextCodePath(Environment.getDataAppDirectory(null), packageName);
3607 int ret = PackageManager.INSTALL_SUCCEEDED;
3609 makeDirRecursive(dstCodePath, 0755);
3610 for (File srcFile : compressedFiles) {
3611 final String srcFileName = srcFile.getName();
3612 final String dstFileName = srcFileName.substring(
3613 0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3614 final File dstFile = new File(dstCodePath, dstFileName);
3615 ret = decompressFile(srcFile, dstFile);
3616 if (ret != PackageManager.INSTALL_SUCCEEDED) {
3617 logCriticalInfo(Log.ERROR, "Failed to decompress"
3618 + "; pkg: " + packageName
3619 + ", file: " + dstFileName);
3623 } catch (ErrnoException e) {
3624 logCriticalInfo(Log.ERROR, "Failed to decompress"
3625 + "; pkg: " + packageName
3626 + ", err: " + e.errno);
3628 if (ret == PackageManager.INSTALL_SUCCEEDED) {
3629 final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3630 NativeLibraryHelper.Handle handle = null;
3632 handle = NativeLibraryHelper.Handle.create(dstCodePath);
3633 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3634 null /*abiOverride*/, false /*isIncremental*/);
3635 } catch (IOException e) {
3636 logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3637 + "; pkg: " + packageName);
3638 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3640 IoUtils.closeQuietly(handle);
3643 if (ret != PackageManager.INSTALL_SUCCEEDED) {
3644 if (!dstCodePath.exists()) {
3647 removeCodePathLI(dstCodePath);
3655 private void updateInstantAppInstallerLocked(String modifiedPackage) {
3656 // we're only interested in updating the installer appliction when 1) it's not
3657 // already set or 2) the modified package is the installer
3658 if (mInstantAppInstallerActivity != null
3659 && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3660 .equals(modifiedPackage)) {
3663 setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3666 private static @Nullable File preparePackageParserCache() {
3667 if (!FORCE_PACKAGE_PARSED_CACHE_ENABLED) {
3668 if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3672 // Disable package parsing on eng builds to allow for faster incremental development.
3677 if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3678 Slog.i(TAG, "Disabling package parser cache due to system property.");
3683 // The base directory for the package parser cache lives under /data/system/.
3684 final File cacheBaseDir = Environment.getPackageCacheDirectory();
3685 if (!FileUtils.createDir(cacheBaseDir)) {
3689 // There are several items that need to be combined together to safely
3690 // identify cached items. In particular, changing the value of certain
3691 // feature flags should cause us to invalidate any caches.
3692 final String cacheName = FORCE_PACKAGE_PARSED_CACHE_ENABLED ? "debug"
3693 : SystemProperties.digestOf(
3694 "ro.build.fingerprint",
3695 StorageManager.PROP_ISOLATED_STORAGE,
3696 StorageManager.PROP_ISOLATED_STORAGE_SNAPSHOT
3699 // Reconcile cache directories, keeping only what we'd actually use.
3700 for (File cacheDir : FileUtils.listFilesOrEmpty(cacheBaseDir)) {
3701 if (Objects.equals(cacheName, cacheDir.getName())) {
3702 Slog.d(TAG, "Keeping known cache " + cacheDir.getName());
3704 Slog.d(TAG, "Destroying unknown cache " + cacheDir.getName());
3705 FileUtils.deleteContentsAndDir(cacheDir);
3709 // Return the versioned package cache directory.
3710 File cacheDir = FileUtils.createDir(cacheBaseDir, cacheName);
3712 if (cacheDir == null) {
3713 // Something went wrong. Attempt to delete everything and return.
3714 Slog.wtf(TAG, "Cache directory cannot be created - wiping base dir " + cacheBaseDir);
3715 FileUtils.deleteContentsAndDir(cacheBaseDir);
3719 // The following is a workaround to aid development on non-numbered userdebug
3720 // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3721 // the system partition is newer.
3723 // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3724 // that starts with "eng." to signify that this is an engineering build and not
3725 // destined for release.
3726 if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3727 Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3729 // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3730 // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3731 // in general and should not be used for production changes. In this specific case,
3732 // we know that they will work.
3733 File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3734 if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3735 FileUtils.deleteContents(cacheBaseDir);
3736 cacheDir = FileUtils.createDir(cacheBaseDir, cacheName);
3744 public boolean isFirstBoot() {
3745 // allow instant applications
3750 public boolean isOnlyCoreApps() {
3751 // allow instant applications
3756 public boolean isDeviceUpgrading() {
3757 // allow instant applications
3758 // The system property allows testing ota flow when upgraded to the same image.
3759 return mIsUpgrade || SystemProperties.getBoolean(
3760 "persist.pm.mock-upgrade", false /* default */);
3763 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3764 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3766 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3767 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3768 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3769 if (matches.size() == 1) {
3770 return matches.get(0).getComponentInfo().packageName;
3771 } else if (matches.size() == 0) {
3772 Log.e(TAG, "There should probably be a verifier, but, none were found");
3775 throw new RuntimeException("There must be exactly one verifier; found " + matches);
3778 private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3779 synchronized (mLock) {
3780 SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(name, version);
3781 if (libraryInfo == null) {
3782 throw new IllegalStateException("Missing required shared library:" + name);
3784 String packageName = libraryInfo.getPackageName();
3785 if (packageName == null) {
3786 throw new IllegalStateException("Expected a package for shared library " + name);
3793 private String getRequiredServicesExtensionPackageLPr() {
3794 String servicesExtensionPackage =
3795 ensureSystemPackageName(
3796 mContext.getString(R.string.config_servicesExtensionPackage));
3797 if (TextUtils.isEmpty(servicesExtensionPackage)) {
3798 throw new RuntimeException(
3799 "Required services extension package is missing, check "
3800 + "config_servicesExtensionPackage.");
3802 return servicesExtensionPackage;
3805 private @NonNull String getRequiredInstallerLPr() {
3806 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3807 intent.addCategory(Intent.CATEGORY_DEFAULT);
3808 intent.setDataAndType(Uri.parse("content://com.example/foo.apk"), PACKAGE_MIME_TYPE);
3810 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3811 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3812 UserHandle.USER_SYSTEM);
3813 if (matches.size() == 1) {
3814 ResolveInfo resolveInfo = matches.get(0);
3815 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3816 throw new RuntimeException("The installer must be a privileged app");
3818 return matches.get(0).getComponentInfo().packageName;
3820 throw new RuntimeException("There must be exactly one installer; found " + matches);
3824 private @NonNull String getRequiredUninstallerLPr() {
3825 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3826 intent.addCategory(Intent.CATEGORY_DEFAULT);
3827 intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3829 final ResolveInfo resolveInfo = resolveIntent(intent, null,
3830 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3831 UserHandle.USER_SYSTEM);
3832 if (resolveInfo == null ||
3833 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3834 throw new RuntimeException("There must be exactly one uninstaller; found "
3837 return resolveInfo.getComponentInfo().packageName;
3840 private @NonNull String getRequiredPermissionControllerLPr() {
3841 final Intent intent = new Intent(Intent.ACTION_MANAGE_PERMISSIONS);
3842 intent.addCategory(Intent.CATEGORY_DEFAULT);
3844 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
3845 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3846 UserHandle.USER_SYSTEM);
3847 if (matches.size() == 1) {
3848 ResolveInfo resolveInfo = matches.get(0);
3849 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3850 throw new RuntimeException("The permissions manager must be a privileged app");
3852 return matches.get(0).getComponentInfo().packageName;
3854 throw new RuntimeException("There must be exactly one permissions manager; found "
3859 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3860 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3862 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3863 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3864 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3865 ResolveInfo best = null;
3866 final int N = matches.size();
3867 for (int i = 0; i < N; i++) {
3868 final ResolveInfo cur = matches.get(i);
3869 final String packageName = cur.getComponentInfo().packageName;
3870 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3871 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3875 if (best == null || cur.priority > best.priority) {
3881 return best.getComponentInfo().getComponentName();
3883 Slog.w(TAG, "Intent filter verifier not found");
3888 public @Nullable ComponentName getInstantAppResolverComponent() {
3889 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3892 synchronized (mLock) {
3893 final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3894 if (instantAppResolver == null) {
3897 return instantAppResolver.first;
3901 private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3902 final String[] packageArray =
3903 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3904 if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3905 if (DEBUG_INSTANT) {
3906 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3911 final int callingUid = Binder.getCallingUid();
3912 final int resolveFlags =
3913 MATCH_DIRECT_BOOT_AWARE
3914 | MATCH_DIRECT_BOOT_UNAWARE
3915 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3916 String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3917 final Intent resolverIntent = new Intent(actionName);
3918 List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3919 resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3920 final int N = resolvers.size();
3922 if (DEBUG_INSTANT) {
3923 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3928 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3929 for (int i = 0; i < N; i++) {
3930 final ResolveInfo info = resolvers.get(i);
3932 if (info.serviceInfo == null) {
3936 final String packageName = info.serviceInfo.packageName;
3937 if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3938 if (DEBUG_INSTANT) {
3939 Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3940 + " pkg: " + packageName + ", info:" + info);
3945 if (DEBUG_INSTANT) {
3946 Slog.v(TAG, "Ephemeral resolver found;"
3947 + " pkg: " + packageName + ", info:" + info);
3949 return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3951 if (DEBUG_INSTANT) {
3952 Slog.v(TAG, "Ephemeral resolver NOT found");
3958 private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3959 String[] orderedActions = Build.IS_ENG
3961 Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE + "_TEST",
3962 Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE}
3964 Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE};
3966 final int resolveFlags =
3967 MATCH_DIRECT_BOOT_AWARE
3968 | MATCH_DIRECT_BOOT_UNAWARE
3969 | Intent.FLAG_IGNORE_EPHEMERAL
3970 | (!Build.IS_ENG ? MATCH_SYSTEM_ONLY : 0);
3971 final Intent intent = new Intent();
3972 intent.addCategory(Intent.CATEGORY_DEFAULT);
3973 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3974 List<ResolveInfo> matches = null;
3975 for (String action : orderedActions) {
3976 intent.setAction(action);
3977 matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3978 resolveFlags, UserHandle.USER_SYSTEM);
3979 if (matches.isEmpty()) {
3980 if (DEBUG_INSTANT) {
3981 Slog.d(TAG, "Instant App installer not found with " + action);
3987 Iterator<ResolveInfo> iter = matches.iterator();
3988 while (iter.hasNext()) {
3989 final ResolveInfo rInfo = iter.next();
3990 final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3992 final PermissionsState permissionsState = ps.getPermissionsState();
3993 if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)
4000 if (matches.size() == 0) {
4002 } else if (matches.size() == 1) {
4003 return (ActivityInfo) matches.get(0).getComponentInfo();
4005 throw new RuntimeException(
4006 "There must be at most one ephemeral installer; found " + matches);
4010 private @Nullable ComponentName getInstantAppResolverSettingsLPr(
4011 @NonNull ComponentName resolver) {
4012 final Intent intent = new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
4013 .addCategory(Intent.CATEGORY_DEFAULT)
4014 .setPackage(resolver.getPackageName());
4015 final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4016 List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
4017 UserHandle.USER_SYSTEM);
4018 if (matches.isEmpty()) {
4021 return matches.get(0).getComponentInfo().getComponentName();
4025 private void primeDomainVerificationsLPw(int userId) {
4026 if (DEBUG_DOMAIN_VERIFICATION) {
4027 Slog.d(TAG, "Priming domain verifications in user " + userId);
4030 SystemConfig systemConfig = SystemConfig.getInstance();
4031 ArraySet<String> packages = systemConfig.getLinkedApps();
4033 for (String packageName : packages) {
4034 AndroidPackage pkg = mPackages.get(packageName);
4036 if (!pkg.isSystem()) {
4037 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
4041 ArraySet<String> domains = null;
4042 for (ParsedActivity a : pkg.getActivities()) {
4043 for (ParsedIntentInfo filter : a.getIntents()) {
4044 if (hasValidDomains(filter)) {
4045 if (domains == null) {
4046 domains = new ArraySet<>();
4048 domains.addAll(filter.getHostsList());
4053 if (domains != null && domains.size() > 0) {
4054 if (DEBUG_DOMAIN_VERIFICATION) {
4055 Slog.v(TAG, " + " + packageName);
4057 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
4058 // state w.r.t. the formal app-linkage "no verification attempted" state;
4059 // and then 'always' in the per-user state actually used for intent resolution.
4060 final IntentFilterVerificationInfo ivi;
4061 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
4062 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
4063 mSettings.updateIntentFilterVerificationStatusLPw(packageName,
4064 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
4066 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
4067 + "' does not handle web links");
4070 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
4074 scheduleWritePackageRestrictionsLocked(userId);
4075 scheduleWriteSettingsLocked();
4078 private boolean packageIsBrowser(String packageName, int userId) {
4079 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
4080 PackageManager.MATCH_ALL, userId);
4081 final int N = list.size();
4082 for (int i = 0; i < N; i++) {
4083 ResolveInfo info = list.get(i);
4084 if (info.priority >= 0 && packageName.equals(info.activityInfo.packageName)) {
4092 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
4093 throws RemoteException {
4095 return super.onTransact(code, data, reply, flags);
4096 } catch (RuntimeException e) {
4097 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
4098 Slog.wtf(TAG, "Package Manager Crash", e);
4105 * Returns whether or not a full application can see an instant application.
4107 * Currently, there are four cases in which this can occur:
4109 * <li>The calling application is a "special" process. Special processes
4110 * are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
4111 * <li>The calling application has the permission
4112 * {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
4113 * <li>The calling application is the default launcher on the
4114 * system partition.</li>
4115 * <li>The calling application is the default app prediction service.</li>
4118 private boolean canViewInstantApps(int callingUid, int userId) {
4119 if (callingUid < Process.FIRST_APPLICATION_UID) {
4122 if (mContext.checkCallingOrSelfPermission(
4123 android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
4126 if (mContext.checkCallingOrSelfPermission(
4127 android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
4128 final ComponentName homeComponent = getDefaultHomeActivity(userId);
4129 if (homeComponent != null
4130 && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
4133 // TODO(b/122900055) Change/Remove this and replace with new permission role.
4134 if (mAppPredictionServicePackage != null
4135 && isCallerSameApp(mAppPredictionServicePackage, callingUid)) {
4142 private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
4143 if (!mUserManager.exists(userId)) return null;
4147 final int callingUid = Binder.getCallingUid();
4148 // Filter out ephemeral app metadata:
4149 // * The system/shell/root can see metadata for any app
4150 // * An installed app can see metadata for 1) other installed apps
4151 // and 2) ephemeral apps that have explicitly interacted with it
4152 // * Ephemeral apps can only see their own data and exposed installed apps
4153 // * Holding a signature permission allows seeing instant apps
4154 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
4158 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
4160 flags |= MATCH_ANY_USER;
4163 final PackageUserState state = ps.readUserState(userId);
4164 AndroidPackage p = ps.pkg;
4166 final PermissionsState permissionsState = ps.getPermissionsState();
4168 // Compute GIDs only if requested
4169 final int[] gids = (flags & PackageManager.GET_GIDS) == 0
4170 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
4171 // Compute granted permissions only if package has requested permissions
4172 final Set<String> permissions = ArrayUtils.isEmpty(p.getRequestedPermissions())
4173 ? Collections.emptySet() : permissionsState.getPermissions(userId);
4175 PackageInfo packageInfo = PackageInfoUtils.generate(p, gids, flags,
4176 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId, ps);
4178 if (packageInfo == null) {
4182 packageInfo.packageName = packageInfo.applicationInfo.packageName =
4183 resolveExternalPackageNameLPr(p);
4186 } else if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 && state.isAvailable(flags)) {
4187 PackageInfo pi = new PackageInfo();
4188 pi.packageName = ps.name;
4189 pi.setLongVersionCode(ps.versionCode);
4190 pi.sharedUserId = (ps.sharedUser != null) ? ps.sharedUser.name : null;
4191 pi.firstInstallTime = ps.firstInstallTime;
4192 pi.lastUpdateTime = ps.lastUpdateTime;
4194 ApplicationInfo ai = new ApplicationInfo();
4195 ai.packageName = ps.name;
4196 ai.uid = UserHandle.getUid(userId, ps.appId);
4197 ai.primaryCpuAbi = ps.primaryCpuAbiString;
4198 ai.secondaryCpuAbi = ps.secondaryCpuAbiString;
4199 ai.setVersionCode(ps.versionCode);
4200 ai.flags = ps.pkgFlags;
4201 ai.privateFlags = ps.pkgPrivateFlags;
4202 pi.applicationInfo = PackageParser.generateApplicationInfo(ai, flags, state, userId);
4204 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "ps.pkg is n/a for ["
4205 + ps.name + "]. Provides a minimum info.");
4213 public void checkPackageStartable(String packageName, int userId) {
4214 final int callingUid = Binder.getCallingUid();
4215 if (getInstantAppPackageName(callingUid) != null) {
4216 throw new SecurityException("Instant applications don't have access to this method");
4218 final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
4219 synchronized (mLock) {
4220 final PackageSetting ps = mSettings.mPackages.get(packageName);
4221 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
4222 throw new SecurityException("Package " + packageName + " was not found!");
4225 if (!ps.getInstalled(userId)) {
4226 throw new SecurityException(
4227 "Package " + packageName + " was not installed for user " + userId + "!");
4230 if (mSafeMode && !ps.isSystem()) {
4231 throw new SecurityException("Package " + packageName + " not a system app!");
4234 if (mFrozenPackages.contains(packageName)) {
4235 throw new SecurityException("Package " + packageName + " is currently frozen!");
4238 if (!userKeyUnlocked && !AndroidPackageUtils.isEncryptionAware(ps.pkg)) {
4239 throw new SecurityException("Package " + packageName + " is not encryption aware!");
4245 public boolean isPackageAvailable(String packageName, int userId) {
4246 if (!mUserManager.exists(userId)) return false;
4247 final int callingUid = Binder.getCallingUid();
4248 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4249 false /*requireFullPermission*/, false /*checkShell*/, "is package available");
4250 synchronized (mLock) {
4251 AndroidPackage p = mPackages.get(packageName);
4253 final PackageSetting ps = getPackageSetting(p.getPackageName());
4254 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
4258 final PackageUserState state = ps.readUserState(userId);
4259 if (state != null) {
4260 return PackageParser.isAvailable(state);
4269 public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
4270 return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
4271 flags, Binder.getCallingUid(), userId);
4275 public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
4276 int flags, int userId) {
4277 return getPackageInfoInternal(versionedPackage.getPackageName(),
4278 versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
4282 * Important: The provided filterCallingUid is used exclusively to filter out packages
4283 * that can be seen based on user state. It's typically the original caller uid prior
4284 * to clearing. Because it can only be provided by trusted code, it's value can be
4285 * trusted and will be used as-is; unlike userId which will be validated by this method.
4287 private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
4288 int flags, int filterCallingUid, int userId) {
4289 if (!mUserManager.exists(userId)) return null;
4290 flags = updateFlagsForPackage(flags, userId);
4291 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4292 false /* requireFullPermission */, false /* checkShell */, "get package info");
4295 synchronized (mLock) {
4296 // Normalize package name to handle renamed packages and static libs
4297 packageName = resolveInternalPackageNameLPr(packageName, versionCode);
4299 final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
4300 if (matchFactoryOnly) {
4301 // Instant app filtering for APEX modules is ignored
4302 if ((flags & MATCH_APEX) != 0) {
4303 return mApexManager.getPackageInfo(packageName,
4304 ApexManager.MATCH_FACTORY_PACKAGE);
4306 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
4308 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4311 if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
4314 return generatePackageInfo(ps, flags, userId);
4318 AndroidPackage p = mPackages.get(packageName);
4319 if (matchFactoryOnly && p != null && !p.isSystem()) {
4322 if (DEBUG_PACKAGE_INFO)
4323 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
4325 final PackageSetting ps = getPackageSetting(p.getPackageName());
4326 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4329 if (ps != null && shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
4333 return generatePackageInfo(ps, flags, userId);
4335 if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
4336 final PackageSetting ps = mSettings.mPackages.get(packageName);
4337 if (ps == null) return null;
4338 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4341 if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
4344 return generatePackageInfo(ps, flags, userId);
4346 if ((flags & MATCH_APEX) != 0) {
4347 return mApexManager.getPackageInfo(packageName, ApexManager.MATCH_ACTIVE_PACKAGE);
4353 private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
4354 if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
4357 if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
4360 if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
4366 private boolean isComponentVisibleToInstantApp(
4367 @Nullable ComponentName component, @ComponentType int type) {
4368 if (type == TYPE_ACTIVITY) {
4369 final ParsedActivity activity = mComponentResolver.getActivity(component);
4370 if (activity == null) {
4373 final boolean visibleToInstantApp =
4374 (activity.getFlags() & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4375 final boolean explicitlyVisibleToInstantApp =
4376 (activity.getFlags() & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
4377 return visibleToInstantApp && explicitlyVisibleToInstantApp;
4378 } else if (type == TYPE_RECEIVER) {
4379 final ParsedActivity activity = mComponentResolver.getReceiver(component);
4380 if (activity == null) {
4383 final boolean visibleToInstantApp =
4384 (activity.getFlags() & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4385 final boolean explicitlyVisibleToInstantApp =
4386 (activity.getFlags() & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
4387 return visibleToInstantApp && !explicitlyVisibleToInstantApp;
4388 } else if (type == TYPE_SERVICE) {
4389 final ParsedService service = mComponentResolver.getService(component);
4390 return service != null
4391 && (service.getFlags() & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4392 } else if (type == TYPE_PROVIDER) {
4393 final ParsedProvider provider = mComponentResolver.getProvider(component);
4394 return provider != null
4395 && (provider.getFlags() & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4396 } else if (type == TYPE_UNKNOWN) {
4397 return isComponentVisibleToInstantApp(component);
4403 * Returns whether or not access to the application should be filtered.
4405 * Access may be limited based upon whether the calling or target applications
4406 * are instant applications.
4408 * @see #canViewInstantApps(int, int)
4411 private boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid,
4412 @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4413 // if we're in an isolated process, get the real calling UID
4414 if (Process.isIsolated(callingUid)) {
4415 callingUid = mIsolatedOwners.get(callingUid);
4417 final String instantAppPkgName = getInstantAppPackageName(callingUid);
4418 final boolean callerIsInstantApp = instantAppPkgName != null;
4420 if (callerIsInstantApp) {
4421 // pretend the application exists, but, needs to be filtered
4426 // if the target and caller are the same application, don't filter
4427 if (isCallerSameApp(ps.name, callingUid)) {
4430 if (callerIsInstantApp) {
4431 // both caller and target are both instant, but, different applications, filter
4432 if (ps.getInstantApp(userId)) {
4435 // request for a specific component; if it hasn't been explicitly exposed through
4436 // property or instrumentation target, filter
4437 if (component != null) {
4438 final ParsedInstrumentation instrumentation =
4439 mInstrumentation.get(component);
4440 if (instrumentation != null
4441 && isCallerSameApp(instrumentation.getTargetPackage(), callingUid)) {
4444 return !isComponentVisibleToInstantApp(component, componentType);
4446 // request for application; if no components have been explicitly exposed, filter
4447 return !ps.pkg.isVisibleToInstantApps();
4449 if (ps.getInstantApp(userId)) {
4450 // caller can see all components of all instant applications, don't filter
4451 if (canViewInstantApps(callingUid, userId)) {
4454 // request for a specific instant application component, filter
4455 if (component != null) {
4458 // request for an instant application; if the caller hasn't been granted access, filter
4459 return !mInstantAppRegistry.isInstantAccessGranted(
4460 userId, UserHandle.getAppId(callingUid), ps.appId);
4462 int appId = UserHandle.getAppId(callingUid);
4463 final SettingBase callingPs = mSettings.getSettingLPr(appId);
4464 return mAppsFilter.shouldFilterApplication(callingUid, callingPs, ps, userId);
4468 * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
4471 private boolean shouldFilterApplicationLocked(
4472 @Nullable PackageSetting ps, int callingUid, int userId) {
4473 return shouldFilterApplicationLocked(ps, callingUid, null, TYPE_UNKNOWN, userId);
4477 private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4479 // Callers can access only the libs they depend on, otherwise they need to explicitly
4480 // ask for the shared libraries given the caller is allowed to access all static libs.
4481 if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4482 // System/shell/root get to see all static libs
4483 final int appId = UserHandle.getAppId(uid);
4484 if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4485 || appId == Process.ROOT_UID) {
4488 // Installer gets to see all static libs.
4489 if (PackageManager.PERMISSION_GRANTED
4490 == checkUidPermission(Manifest.permission.INSTALL_PACKAGES, uid)) {
4495 // No package means no static lib as it is always on internal storage
4496 if (ps == null || ps.pkg == null || !ps.pkg.isStaticSharedLibrary()) {
4500 final SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(
4501 ps.pkg.getStaticSharedLibName(), ps.pkg.getStaticSharedLibVersion());
4502 if (libraryInfo == null) {
4506 final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4507 final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4508 if (uidPackageNames == null) {
4512 for (String uidPackageName : uidPackageNames) {
4513 if (ps.name.equals(uidPackageName)) {
4516 PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4517 if (uidPs != null) {
4518 final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4519 libraryInfo.getName());
4523 if (uidPs.pkg.getUsesStaticLibrariesVersions()[index]
4524 == libraryInfo.getLongVersion()) {
4533 public String[] currentToCanonicalPackageNames(String[] names) {
4534 final int callingUid = Binder.getCallingUid();
4535 if (getInstantAppPackageName(callingUid) != null) {
4538 final String[] out = new String[names.length];
4540 synchronized (mLock) {
4541 final int callingUserId = UserHandle.getUserId(callingUid);
4542 final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4543 for (int i=names.length-1; i>=0; i--) {
4544 final PackageSetting ps = mSettings.mPackages.get(names[i]);
4545 boolean translateName = false;
4546 if (ps != null && ps.realName != null) {
4547 final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4548 translateName = !targetIsInstantApp
4549 || canViewInstantApps
4550 || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4551 UserHandle.getAppId(callingUid), ps.appId);
4553 out[i] = translateName ? ps.realName : names[i];
4560 public String[] canonicalToCurrentPackageNames(String[] names) {
4561 final int callingUid = Binder.getCallingUid();
4562 if (getInstantAppPackageName(callingUid) != null) {
4565 final String[] out = new String[names.length];
4567 synchronized (mLock) {
4568 final int callingUserId = UserHandle.getUserId(callingUid);
4569 final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4570 for (int i=names.length-1; i>=0; i--) {
4571 final String cur = mSettings.getRenamedPackageLPr(names[i]);
4572 boolean translateName = false;
4574 final PackageSetting ps = mSettings.mPackages.get(names[i]);
4575 final boolean targetIsInstantApp =
4576 ps != null && ps.getInstantApp(callingUserId);
4577 translateName = !targetIsInstantApp
4578 || canViewInstantApps
4579 || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4580 UserHandle.getAppId(callingUid), ps.appId);
4582 out[i] = translateName ? cur : names[i];
4589 public int getPackageUid(String packageName, int flags, int userId) {
4590 if (!mUserManager.exists(userId)) return -1;
4591 final int callingUid = Binder.getCallingUid();
4592 flags = updateFlagsForPackage(flags, userId);
4593 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4594 false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4595 return getPackageUidInternal(packageName, flags, userId, callingUid);
4598 private int getPackageUidInternal(String packageName, int flags, int userId, int callingUid) {
4600 synchronized (mLock) {
4601 final AndroidPackage p = mPackages.get(packageName);
4602 if (p != null && AndroidPackageUtils.isMatchForSystemOnly(p, flags)) {
4603 PackageSetting ps = getPackageSettingInternal(p.getPackageName(), callingUid);
4604 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
4607 return UserHandle.getUid(userId, p.getUid());
4609 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4610 final PackageSetting ps = mSettings.mPackages.get(packageName);
4611 if (ps != null && ps.isMatch(flags)
4612 && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
4613 return UserHandle.getUid(userId, ps.appId);
4622 public int[] getPackageGids(String packageName, int flags, int userId) {
4623 if (!mUserManager.exists(userId)) return null;
4624 final int callingUid = Binder.getCallingUid();
4625 flags = updateFlagsForPackage(flags, userId);
4626 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4627 false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4630 synchronized (mLock) {
4631 final AndroidPackage p = mPackages.get(packageName);
4632 if (p != null && AndroidPackageUtils.isMatchForSystemOnly(p, flags)) {
4633 PackageSetting ps = getPackageSetting(p.getPackageName());
4634 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
4637 // TODO: Shouldn't this be checking for package installed state for userId and
4639 return ps.getPermissionsState().computeGids(userId);
4641 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4642 final PackageSetting ps = mSettings.mPackages.get(packageName);
4643 if (ps != null && ps.isMatch(flags)
4644 && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
4645 return ps.getPermissionsState().computeGids(userId);
4653 // NOTE: Can't remove due to unsupported app usage
4655 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
4657 // Because this is accessed via the package manager service AIDL,
4658 // go through the permission manager service AIDL
4659 return mPermissionManagerService.getPermissionGroupInfo(groupName, flags);
4660 } catch (RemoteException ignore) { }
4665 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4666 int filterCallingUid, int userId) {
4667 if (!mUserManager.exists(userId)) return null;
4668 PackageSetting ps = mSettings.mPackages.get(packageName);
4670 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4673 if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
4676 if (ps.pkg == null) {
4677 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4678 if (pInfo != null) {
4679 return pInfo.applicationInfo;
4683 ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(ps.pkg, flags,
4684 ps.readUserState(userId), userId, ps);
4686 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4694 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4695 return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4699 * Important: The provided filterCallingUid is used exclusively to filter out applications
4700 * that can be seen based on user state. It's typically the original caller uid prior
4701 * to clearing. Because it can only be provided by trusted code, it's value can be
4702 * trusted and will be used as-is; unlike userId which will be validated by this method.
4704 private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4705 int filterCallingUid, int userId) {
4706 if (!mUserManager.exists(userId)) return null;
4707 flags = updateFlagsForApplication(flags, userId);
4709 if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
4710 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4711 false /* requireFullPermission */, false /* checkShell */,
4712 "get application info");
4716 synchronized (mLock) {
4717 // Normalize package name to handle renamed packages and static libs
4718 packageName = resolveInternalPackageNameLPr(packageName,
4719 PackageManager.VERSION_CODE_HIGHEST);
4721 AndroidPackage p = mPackages.get(packageName);
4722 if (DEBUG_PACKAGE_INFO) Log.v(
4723 TAG, "getApplicationInfo " + packageName
4726 PackageSetting ps = mSettings.mPackages.get(packageName);
4727 if (ps == null) return null;
4728 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4731 if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
4734 // Note: isEnabledLP() does not apply here - always return info
4735 ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(
4736 p, flags, ps.readUserState(userId), userId, ps);
4738 ai.packageName = resolveExternalPackageNameLPr(p);
4742 if ("android".equals(packageName)||"system".equals(packageName)) {
4743 return mAndroidApplication;
4745 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4746 // Already generates the external package name
4747 return generateApplicationInfoFromSettingsLPw(packageName,
4748 flags, filterCallingUid, userId);
4755 private String normalizePackageNameLPr(String packageName) {
4756 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4757 return normalizedPackageName != null ? normalizedPackageName : packageName;
4761 public void deletePreloadsFileCache() {
4762 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CLEAR_APP_CACHE,
4763 "deletePreloadsFileCache");
4764 File dir = Environment.getDataPreloadsFileCacheDirectory();
4765 Slog.i(TAG, "Deleting preloaded file cache " + dir);
4766 FileUtils.deleteContents(dir);
4770 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4771 final int storageFlags, final IPackageDataObserver observer) {
4772 mContext.enforceCallingOrSelfPermission(
4773 android.Manifest.permission.CLEAR_APP_CACHE, null);
4774 mHandler.post(() -> {
4775 boolean success = false;
4777 freeStorage(volumeUuid, freeStorageSize, storageFlags);
4779 } catch (IOException e) {
4782 if (observer != null) {
4784 observer.onRemoveCompleted(null, success);
4785 } catch (RemoteException e) {
4793 public void freeStorage(final String volumeUuid, final long freeStorageSize,
4794 final int storageFlags, final IntentSender pi) {
4795 mContext.enforceCallingOrSelfPermission(
4796 android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4797 mHandler.post(() -> {
4798 boolean success = false;
4800 freeStorage(volumeUuid, freeStorageSize, storageFlags);
4802 } catch (IOException e) {
4807 pi.sendIntent(null, success ? 1 : 0, null, null, null);
4808 } catch (SendIntentException e) {
4816 * Blocking call to clear various types of cached data across the system
4817 * until the requested bytes are available.
4819 public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4820 final StorageManager storage = mInjector.getStorageManager();
4821 final File file = storage.findPathForUuid(volumeUuid);
4822 if (file.getUsableSpace() >= bytes) return;
4824 if (ENABLE_FREE_CACHE_V2) {
4825 final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4827 final boolean aggressive = (storageFlags
4828 & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4829 final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4831 // 1. Pre-flight to determine if we have any chance to succeed
4832 // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4833 if (internalVolume && (aggressive || SystemProperties
4834 .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4835 deletePreloadsFileCache();
4836 if (file.getUsableSpace() >= bytes) return;
4839 // 3. Consider parsed APK data (aggressive only)
4840 if (internalVolume && aggressive) {
4841 FileUtils.deleteContents(mCacheDir);
4842 if (file.getUsableSpace() >= bytes) return;
4845 // 4. Consider cached app data (above quotas)
4847 mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4848 Installer.FLAG_FREE_CACHE_V2);
4849 } catch (InstallerException ignored) {
4851 if (file.getUsableSpace() >= bytes) return;
4853 // 5. Consider shared libraries with refcount=0 and age>min cache period
4854 if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4855 android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4856 Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4857 DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4861 // 6. Consider dexopt output (aggressive only)
4864 // 7. Consider installed instant apps unused longer than min cache period
4865 if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4866 android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4867 Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4868 InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4872 // 8. Consider cached app data (below quotas)
4874 mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4875 Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4876 } catch (InstallerException ignored) {
4878 if (file.getUsableSpace() >= bytes) return;
4880 // 9. Consider DropBox entries
4883 // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4884 if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4885 android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4886 Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4887 InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4892 mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4893 } catch (InstallerException ignored) {
4895 if (file.getUsableSpace() >= bytes) return;
4898 throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4901 private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4902 throws IOException {
4903 final StorageManager storage = mInjector.getStorageManager();
4904 final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4906 List<VersionedPackage> packagesToDelete = null;
4907 final long now = System.currentTimeMillis();
4909 synchronized (mLock) {
4910 final int[] allUsers = mUserManager.getUserIds();
4911 final int libCount = mSharedLibraries.size();
4912 for (int i = 0; i < libCount; i++) {
4913 final LongSparseArray<SharedLibraryInfo> versionedLib
4914 = mSharedLibraries.valueAt(i);
4915 if (versionedLib == null) {
4918 final int versionCount = versionedLib.size();
4919 for (int j = 0; j < versionCount; j++) {
4920 SharedLibraryInfo libInfo = versionedLib.valueAt(j);
4921 // Skip packages that are not static shared libs.
4922 if (!libInfo.isStatic()) {
4925 // Important: We skip static shared libs used for some user since
4926 // in such a case we need to keep the APK on the device. The check for
4927 // a lib being used for any user is performed by the uninstall call.
4928 final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4929 // Resolve the package name - we use synthetic package names internally
4930 final String internalPackageName = resolveInternalPackageNameLPr(
4931 declaringPackage.getPackageName(),
4932 declaringPackage.getLongVersionCode());
4933 final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4934 // Skip unused static shared libs cached less than the min period
4935 // to prevent pruning a lib needed by a subsequently installed package.
4936 if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4940 if (ps.pkg.isSystem()) {
4944 if (packagesToDelete == null) {
4945 packagesToDelete = new ArrayList<>();
4947 packagesToDelete.add(new VersionedPackage(internalPackageName,
4948 declaringPackage.getLongVersionCode()));
4953 if (packagesToDelete != null) {
4954 final int packageCount = packagesToDelete.size();
4955 for (int i = 0; i < packageCount; i++) {
4956 final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4957 // Delete the package synchronously (will fail of the lib used for any user).
4958 if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getLongVersionCode(),
4959 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4960 == PackageManager.DELETE_SUCCEEDED) {
4961 if (volume.getUsableSpace() >= neededSpace) {
4972 * Update given flags based on encryption status of current user.
4974 private int updateFlags(int flags, int userId) {
4975 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4976 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4977 // Caller expressed an explicit opinion about what encryption
4978 // aware/unaware components they want to see, so fall through and
4979 // give them what they want
4981 // Caller expressed no opinion, so match based on user state
4982 if (mUserManager.isUserUnlockingOrUnlocked(userId)) {
4983 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4985 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4992 * Update given flags when being used to request {@link PackageInfo}.
4994 private int updateFlagsForPackage(int flags, int userId) {
4995 final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4996 if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4997 // require the permission to be held; the calling uid and given user id referring
4998 // to the same user is not sufficient
4999 mPermissionManager.enforceCrossUserPermission(
5000 Binder.getCallingUid(), userId, false, false,
5001 !isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId),
5002 "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
5003 + Debug.getCallers(5));
5004 } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
5005 && mUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
5006 // If the caller wants all packages and has a restricted profile associated with it,
5007 // then match all users. This is to make sure that launchers that need to access work
5008 // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
5009 // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
5010 flags |= PackageManager.MATCH_ANY_USER;
5012 return updateFlags(flags, userId);
5016 * Update given flags when being used to request {@link ApplicationInfo}.
5018 private int updateFlagsForApplication(int flags, int userId) {
5019 return updateFlagsForPackage(flags, userId);
5023 * Update given flags when being used to request {@link ComponentInfo}.
5025 private int updateFlagsForComponent(int flags, int userId) {
5026 return updateFlags(flags, userId);
5030 * Update given intent when being used to request {@link ResolveInfo}.
5032 private Intent updateIntentForResolve(Intent intent) {
5033 if (intent.getSelector() != null) {
5034 intent = intent.getSelector();
5036 if (DEBUG_PREFERRED) {
5037 intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
5043 * Update given flags when being used to request {@link ResolveInfo}.
5044 * <p>Instant apps are resolved specially, depending upon context. Minimally,
5045 * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
5046 * flag set. However, this flag is only honoured in three circumstances:
5048 * <li>when called from a system process</li>
5049 * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
5050 * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
5051 * action and a {@code android.intent.category.BROWSABLE} category</li>
5054 int updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps) {
5055 return updateFlagsForResolve(flags, userId, callingUid,
5056 wantInstantApps, false /*onlyExposedExplicitly*/);
5059 int updateFlagsForResolve(int flags, int userId, int callingUid,
5060 boolean wantInstantApps, boolean onlyExposedExplicitly) {
5061 // Safe mode means we shouldn't match any third-party components
5063 flags |= PackageManager.MATCH_SYSTEM_ONLY;
5065 if (getInstantAppPackageName(callingUid) != null) {
5066 // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
5067 if (onlyExposedExplicitly) {
5068 flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
5070 flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
5071 flags |= PackageManager.MATCH_INSTANT;
5073 final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
5074 final boolean allowMatchInstant = wantInstantApps
5075 || (wantMatchInstant && canViewInstantApps(callingUid, userId));
5076 flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
5077 | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
5078 if (!allowMatchInstant) {
5079 flags &= ~PackageManager.MATCH_INSTANT;
5082 return updateFlagsForComponent(flags, userId);
5086 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
5087 return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
5091 * Important: The provided filterCallingUid is used exclusively to filter out activities
5092 * that can be seen based on user state. It's typically the original caller uid prior
5093 * to clearing. Because it can only be provided by trusted code, it's value can be
5094 * trusted and will be used as-is; unlike userId which will be validated by this method.
5096 private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
5097 int filterCallingUid, int userId) {
5098 if (!mUserManager.exists(userId)) return null;
5099 flags = updateFlagsForComponent(flags, userId);
5101 if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
5102 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
5103 false /* requireFullPermission */, false /* checkShell */, "get activity info");
5106 synchronized (mLock) {
5107 ParsedActivity a = mComponentResolver.getActivity(component);
5109 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
5111 AndroidPackage pkg = a == null ? null : mPackages.get(a.getPackageName());
5112 if (pkg != null && mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) {
5113 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5114 if (ps == null) return null;
5115 if (shouldFilterApplicationLocked(
5116 ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
5119 return PackageInfoUtils.generateActivityInfo(pkg,
5120 a, flags, ps.readUserState(userId), userId, ps);
5122 if (mResolveComponentName.equals(component)) {
5123 return PackageParser.generateActivityInfo(
5124 mResolveActivity, flags, new PackageUserState(), userId);
5130 private boolean isRecentsAccessingChildProfiles(int callingUid, int targetUserId) {
5131 if (!mInjector.getActivityTaskManagerInternal().isCallerRecents(callingUid)) {
5134 final long token = Binder.clearCallingIdentity();
5136 final int callingUserId = UserHandle.getUserId(callingUid);
5137 if (ActivityManager.getCurrentUser() != callingUserId) {
5140 return mUserManager.isSameProfileGroup(callingUserId, targetUserId);
5142 Binder.restoreCallingIdentity(token);
5147 public boolean activitySupportsIntent(ComponentName component, Intent intent,
5148 String resolvedType) {
5149 synchronized (mLock) {
5150 if (component.equals(mResolveComponentName)) {
5151 // The resolver supports EVERYTHING!
5154 final int callingUid = Binder.getCallingUid();
5155 final int callingUserId = UserHandle.getUserId(callingUid);
5156 ParsedActivity a = mComponentResolver.getActivity(component);
5160 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5164 if (shouldFilterApplicationLocked(
5165 ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
5168 for (int i=0; i< a.getIntents().size(); i++) {
5169 if (a.getIntents().get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
5170 intent.getData(), intent.getCategories(), TAG) >= 0) {
5179 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
5180 if (!mUserManager.exists(userId)) return null;
5181 final int callingUid = Binder.getCallingUid();
5182 flags = updateFlagsForComponent(flags, userId);
5183 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5184 false /* requireFullPermission */, false /* checkShell */, "get receiver info");
5185 synchronized (mLock) {
5186 ParsedActivity a = mComponentResolver.getReceiver(component);
5187 if (DEBUG_PACKAGE_INFO) Log.v(
5188 TAG, "getReceiverInfo " + component + ": " + a);
5194 AndroidPackage pkg = mPackages.get(a.getPackageName());
5199 if (mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) {
5200 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5201 if (ps == null) return null;
5202 if (shouldFilterApplicationLocked(
5203 ps, callingUid, component, TYPE_RECEIVER, userId)) {
5206 return PackageInfoUtils.generateActivityInfo(pkg,
5207 a, flags, ps.readUserState(userId), userId, ps);
5214 public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
5215 int flags, int userId) {
5216 if (!mUserManager.exists(userId)) return null;
5217 Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
5218 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5222 flags = updateFlagsForPackage(flags, userId);
5224 final boolean canSeeStaticLibraries =
5225 mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
5226 == PERMISSION_GRANTED
5227 || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
5228 == PERMISSION_GRANTED
5229 || canRequestPackageInstallsInternal(packageName,
5230 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
5231 false /* throwIfPermNotDeclared*/)
5232 || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
5233 == PERMISSION_GRANTED
5234 || mContext.checkCallingOrSelfPermission(
5235 Manifest.permission.ACCESS_SHARED_LIBRARIES) == PERMISSION_GRANTED;
5237 synchronized (mLock) {
5238 List<SharedLibraryInfo> result = null;
5240 final int libCount = mSharedLibraries.size();
5241 for (int i = 0; i < libCount; i++) {
5242 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.valueAt(i);
5243 if (versionedLib == null) {
5247 final int versionCount = versionedLib.size();
5248 for (int j = 0; j < versionCount; j++) {
5249 SharedLibraryInfo libInfo = versionedLib.valueAt(j);
5250 if (!canSeeStaticLibraries && libInfo.isStatic()) {
5253 final long identity = Binder.clearCallingIdentity();
5255 PackageInfo packageInfo = getPackageInfoVersioned(
5256 libInfo.getDeclaringPackage(), flags
5257 | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
5258 if (packageInfo == null) {
5262 Binder.restoreCallingIdentity(identity);
5265 SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getPath(),
5266 libInfo.getPackageName(), libInfo.getAllCodePaths(),
5267 libInfo.getName(), libInfo.getLongVersion(),
5268 libInfo.getType(), libInfo.getDeclaringPackage(),
5269 getPackagesUsingSharedLibraryLPr(libInfo, flags, userId),
5270 (libInfo.getDependencies() == null
5272 : new ArrayList<>(libInfo.getDependencies())));
5274 if (result == null) {
5275 result = new ArrayList<>();
5277 result.add(resLibInfo);
5281 return result != null ? new ParceledListSlice<>(result) : null;
5287 public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
5288 @NonNull String packageName, int flags, @NonNull int userId) {
5289 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_SHARED_LIBRARIES,
5290 "getDeclaredSharedLibraries");
5291 int callingUid = Binder.getCallingUid();
5292 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5293 true /* requireFullPermission */, false /* checkShell */,
5294 "getDeclaredSharedLibraries");
5296 Preconditions.checkNotNull(packageName, "packageName cannot be null");
5297 Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
5298 if (!mUserManager.exists(userId)) {
5302 if (getInstantAppPackageName(callingUid) != null) {
5306 synchronized (mLock) {
5307 List<SharedLibraryInfo> result = null;
5309 int libraryCount = mSharedLibraries.size();
5310 for (int i = 0; i < libraryCount; i++) {
5311 LongSparseArray<SharedLibraryInfo> versionedLibrary = mSharedLibraries.valueAt(i);
5312 if (versionedLibrary == null) {
5316 int versionCount = versionedLibrary.size();
5317 for (int j = 0; j < versionCount; j++) {
5318 SharedLibraryInfo libraryInfo = versionedLibrary.valueAt(j);
5320 VersionedPackage declaringPackage = libraryInfo.getDeclaringPackage();
5321 if (!Objects.equals(declaringPackage.getPackageName(), packageName)) {
5325 long identity = Binder.clearCallingIdentity();
5327 PackageInfo packageInfo = getPackageInfoVersioned(declaringPackage, flags
5328 | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
5329 if (packageInfo == null) {
5333 Binder.restoreCallingIdentity(identity);
5336 SharedLibraryInfo resultLibraryInfo = new SharedLibraryInfo(
5337 libraryInfo.getPath(), libraryInfo.getPackageName(),
5338 libraryInfo.getAllCodePaths(), libraryInfo.getName(),
5339 libraryInfo.getLongVersion(), libraryInfo.getType(),
5340 libraryInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(
5341 libraryInfo, flags, userId), libraryInfo.getDependencies() == null
5342 ? null : new ArrayList<>(libraryInfo.getDependencies()));
5344 if (result == null) {
5345 result = new ArrayList<>();
5347 result.add(resultLibraryInfo);
5351 return result != null ? new ParceledListSlice<>(result) : null;
5356 private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
5357 SharedLibraryInfo libInfo, int flags, int userId) {
5358 List<VersionedPackage> versionedPackages = null;
5359 final int packageCount = mSettings.mPackages.size();
5360 for (int i = 0; i < packageCount; i++) {
5361 PackageSetting ps = mSettings.mPackages.valueAt(i);
5367 if (!ps.readUserState(userId).isAvailable(flags)) {
5371 final String libName = libInfo.getName();
5372 if (libInfo.isStatic()) {
5373 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
5377 if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getLongVersion()) {
5380 if (versionedPackages == null) {
5381 versionedPackages = new ArrayList<>();
5383 // If the dependent is a static shared lib, use the public package name
5384 String dependentPackageName = ps.name;
5385 if (ps.pkg != null && ps.pkg.isStaticSharedLibrary()) {
5386 dependentPackageName = ps.pkg.getManifestPackageName();
5388 versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
5389 } else if (ps.pkg != null) {
5390 if (ArrayUtils.contains(ps.pkg.getUsesLibraries(), libName)
5391 || ArrayUtils.contains(ps.pkg.getUsesOptionalLibraries(), libName)) {
5392 if (versionedPackages == null) {
5393 versionedPackages = new ArrayList<>();
5395 versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
5400 return versionedPackages;
5404 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5405 if (!mUserManager.exists(userId)) return null;
5406 final int callingUid = Binder.getCallingUid();
5407 flags = updateFlagsForComponent(flags, userId);
5408 mPermissionManager.enforceCrossUserOrProfilePermission(
5409 callingUid, userId, false /* requireFullPermission */, false /* checkShell */,
5410 "get service info");
5411 synchronized (mLock) {
5412 ParsedService s = mComponentResolver.getService(component);
5413 if (DEBUG_PACKAGE_INFO) Log.v(
5414 TAG, "getServiceInfo " + component + ": " + s);
5419 AndroidPackage pkg = mPackages.get(s.getPackageName());
5420 if (mSettings.isEnabledAndMatchLPr(pkg, s, flags, userId)) {
5421 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5422 if (ps == null) return null;
5423 if (shouldFilterApplicationLocked(
5424 ps, callingUid, component, TYPE_SERVICE, userId)) {
5427 return PackageInfoUtils.generateServiceInfo(pkg,
5428 s, flags, ps.readUserState(userId), userId, ps);
5435 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
5436 if (!mUserManager.exists(userId)) return null;
5437 final int callingUid = Binder.getCallingUid();
5438 flags = updateFlagsForComponent(flags, userId);
5439 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5440 false /* requireFullPermission */, false /* checkShell */, "get provider info");
5441 synchronized (mLock) {
5442 ParsedProvider p = mComponentResolver.getProvider(component);
5443 if (DEBUG_PACKAGE_INFO) Log.v(
5444 TAG, "getProviderInfo " + component + ": " + p);
5449 AndroidPackage pkg = mPackages.get(p.getPackageName());
5454 if (mSettings.isEnabledAndMatchLPr(pkg, p, flags, userId)) {
5455 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5456 if (ps == null) return null;
5457 if (shouldFilterApplicationLocked(
5458 ps, callingUid, component, TYPE_PROVIDER, userId)) {
5461 PackageUserState state = ps.readUserState(userId);
5462 final ApplicationInfo appInfo = PackageInfoUtils.generateApplicationInfo(
5463 pkg, flags, state, userId, ps);
5464 if (appInfo == null) {
5467 return PackageInfoUtils.generateProviderInfo(
5468 pkg, p, flags, state, appInfo, userId, ps);
5475 public ModuleInfo getModuleInfo(String packageName, @ModuleInfoFlags int flags) {
5476 return mModuleInfoProvider.getModuleInfo(packageName, flags);
5480 public List<ModuleInfo> getInstalledModules(int flags) {
5481 return mModuleInfoProvider.getInstalledModules(flags);
5485 public String[] getSystemSharedLibraryNames() {
5486 // allow instant applications
5487 synchronized (mLock) {
5488 Set<String> libs = null;
5489 final int libCount = mSharedLibraries.size();
5490 for (int i = 0; i < libCount; i++) {
5491 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.valueAt(i);
5492 if (versionedLib == null) {
5495 final int versionCount = versionedLib.size();
5496 for (int j = 0; j < versionCount; j++) {
5497 SharedLibraryInfo libraryInfo = versionedLib.valueAt(j);
5498 if (!libraryInfo.isStatic()) {
5500 libs = new ArraySet<>();
5502 libs.add(libraryInfo.getName());
5505 PackageSetting ps = mSettings.getPackageLPr(libraryInfo.getPackageName());
5506 if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
5507 UserHandle.getUserId(Binder.getCallingUid()),
5508 PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
5510 libs = new ArraySet<>();
5512 libs.add(libraryInfo.getName());
5519 String[] libsArray = new String[libs.size()];
5520 libs.toArray(libsArray);
5529 public @NonNull String getServicesSystemSharedLibraryPackageName() {
5530 // allow instant applications
5531 synchronized (mLock) {
5532 return mServicesExtensionPackageName;
5537 public @NonNull String getSharedSystemSharedLibraryPackageName() {
5538 // allow instant applications
5539 synchronized (mLock) {
5540 return mSharedSystemSharedLibraryPackageName;
5545 private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5546 for (int i = userList.length - 1; i >= 0; --i) {
5547 final int userId = userList[i];
5548 // don't add instant app to the list of updates
5549 if (pkgSetting.getInstantApp(userId)) {
5552 SparseArray<String> changedPackages = mChangedPackages.get(userId);
5553 if (changedPackages == null) {
5554 changedPackages = new SparseArray<>();
5555 mChangedPackages.put(userId, changedPackages);
5557 Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5558 if (sequenceNumbers == null) {
5559 sequenceNumbers = new HashMap<>();
5560 mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5562 final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5563 if (sequenceNumber != null) {
5564 changedPackages.remove(sequenceNumber);
5566 changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5567 sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5569 mChangedPackagesSequenceNumber++;
5573 public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5574 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5577 synchronized (mLock) {
5578 if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5581 final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5582 if (changedPackages == null) {
5585 final List<String> packageNames =
5586 new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5587 for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5588 final String packageName = changedPackages.get(i);
5589 if (packageName != null) {
5590 packageNames.add(packageName);
5593 return packageNames.isEmpty()
5594 ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5599 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5600 // allow instant applications
5601 ArrayList<FeatureInfo> res;
5602 synchronized (mAvailableFeatures) {
5603 res = new ArrayList<>(mAvailableFeatures.size() + 1);
5604 res.addAll(mAvailableFeatures.values());
5606 final FeatureInfo fi = new FeatureInfo();
5607 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5608 FeatureInfo.GL_ES_VERSION_UNDEFINED);
5611 return new ParceledListSlice<>(res);
5615 public boolean hasSystemFeature(String name, int version) {
5616 // allow instant applications
5617 synchronized (mAvailableFeatures) {
5618 final FeatureInfo feat = mAvailableFeatures.get(name);
5622 return feat.version >= version;
5627 // NOTE: Can't remove due to unsupported app usage
5629 public int checkPermission(String permName, String pkgName, int userId) {
5631 // Because this is accessed via the package manager service AIDL,
5632 // go through the permission manager service AIDL
5633 return mPermissionManagerService.checkPermission(permName, pkgName, userId);
5634 } catch (RemoteException ignore) { }
5635 return PackageManager.PERMISSION_DENIED;
5638 // NOTE: Can't remove without a major refactor. Keep around for now.
5640 public int checkUidPermission(String permName, int uid) {
5642 // Because this is accessed via the package manager service AIDL,
5643 // go through the permission manager service AIDL
5644 return mPermissionManagerService.checkUidPermission(permName, uid);
5645 } catch (RemoteException ignore) { }
5646 return PackageManager.PERMISSION_DENIED;
5650 public String getPermissionControllerPackageName() {
5651 synchronized (mLock) {
5652 return mRequiredPermissionControllerPackage;
5656 String getPackageInstallerPackageName() {
5657 synchronized (mLock) {
5658 return mRequiredInstallerPackage;
5662 // NOTE: Can't remove due to unsupported app usage
5664 public boolean addPermission(PermissionInfo info) {
5666 // Because this is accessed via the package manager service AIDL,
5667 // go through the permission manager service AIDL
5668 return mPermissionManagerService.addPermission(info, false);
5669 } catch (RemoteException ignore) { }
5673 // NOTE: Can't remove due to unsupported app usage
5675 public boolean addPermissionAsync(PermissionInfo info) {
5677 // Because this is accessed via the package manager service AIDL,
5678 // go through the permission manager service AIDL
5679 return mPermissionManagerService.addPermission(info, true);
5680 } catch (RemoteException ignore) { }
5684 // NOTE: Can't remove due to unsupported app usage
5686 public void removePermission(String permName) {
5688 // Because this is accessed via the package manager service AIDL,
5689 // go through the permission manager service AIDL
5690 mPermissionManagerService.removePermission(permName);
5691 } catch (RemoteException ignore) { }
5694 // NOTE: Can't remove due to unsupported app usage
5696 public void grantRuntimePermission(String packageName, String permName, final int userId) {
5698 // Because this is accessed via the package manager service AIDL,
5699 // go through the permission manager service AIDL
5700 mPermissionManagerService.grantRuntimePermission(packageName, permName, userId);
5701 } catch (RemoteException ignore) { }
5705 public boolean isProtectedBroadcast(String actionName) {
5706 // allow instant applications
5707 synchronized (mProtectedBroadcasts) {
5708 if (mProtectedBroadcasts.contains(actionName)) {
5710 } else if (actionName != null) {
5711 // TODO: remove these terrible hacks
5712 if (actionName.startsWith("android.net.netmon.lingerExpired")
5713 || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5714 || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5715 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5724 public int checkSignatures(String pkg1, String pkg2) {
5725 synchronized (mLock) {
5726 final AndroidPackage p1 = mPackages.get(pkg1);
5727 final AndroidPackage p2 = mPackages.get(pkg2);
5728 final PackageSetting ps1 = p1 == null ? null : getPackageSetting(p1.getPackageName());
5729 final PackageSetting ps2 = p2 == null ? null : getPackageSetting(p2.getPackageName());
5730 if (p1 == null || ps1 == null || p2 == null || ps2 == null) {
5731 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5733 final int callingUid = Binder.getCallingUid();
5734 final int callingUserId = UserHandle.getUserId(callingUid);
5735 if (shouldFilterApplicationLocked(ps1, callingUid, callingUserId)
5736 || shouldFilterApplicationLocked(ps2, callingUid, callingUserId)) {
5737 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5739 return compareSignatures(p1.getSigningDetails().signatures,
5740 p2.getSigningDetails().signatures);
5745 public int checkUidSignatures(int uid1, int uid2) {
5746 final int callingUid = Binder.getCallingUid();
5747 final int callingUserId = UserHandle.getUserId(callingUid);
5748 final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5749 // Map to base uids.
5750 final int appId1 = UserHandle.getAppId(uid1);
5751 final int appId2 = UserHandle.getAppId(uid2);
5753 synchronized (mLock) {
5756 Object obj = mSettings.getSettingLPr(appId1);
5758 if (obj instanceof SharedUserSetting) {
5759 if (isCallerInstantApp) {
5760 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5762 s1 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
5763 } else if (obj instanceof PackageSetting) {
5764 final PackageSetting ps = (PackageSetting) obj;
5765 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
5766 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5768 s1 = ps.signatures.mSigningDetails.signatures;
5770 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5773 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5775 obj = mSettings.getSettingLPr(appId2);
5777 if (obj instanceof SharedUserSetting) {
5778 if (isCallerInstantApp) {
5779 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5781 s2 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
5782 } else if (obj instanceof PackageSetting) {
5783 final PackageSetting ps = (PackageSetting) obj;
5784 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
5785 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5787 s2 = ps.signatures.mSigningDetails.signatures;
5789 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5792 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5794 return compareSignatures(s1, s2);
5799 public boolean hasSigningCertificate(
5800 String packageName, byte[] certificate, @PackageManager.CertificateInputType int type) {
5802 synchronized (mLock) {
5803 final AndroidPackage p = mPackages.get(packageName);
5804 final PackageSetting ps = getPackageSetting(p.getPackageName());
5805 if (p == null || ps == null) {
5808 final int callingUid = Binder.getCallingUid();
5809 final int callingUserId = UserHandle.getUserId(callingUid);
5810 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
5814 case CERT_INPUT_RAW_X509:
5815 return p.getSigningDetails().hasCertificate(certificate);
5816 case CERT_INPUT_SHA256:
5817 return p.getSigningDetails().hasSha256Certificate(certificate);
5825 public boolean hasUidSigningCertificate(
5826 int uid, byte[] certificate, @PackageManager.CertificateInputType int type) {
5827 final int callingUid = Binder.getCallingUid();
5828 final int callingUserId = UserHandle.getUserId(callingUid);
5829 // Map to base uids.
5830 final int appId = UserHandle.getAppId(uid);
5832 synchronized (mLock) {
5833 final PackageParser.SigningDetails signingDetails;
5834 final Object obj = mSettings.getSettingLPr(appId);
5836 if (obj instanceof SharedUserSetting) {
5837 final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5838 if (isCallerInstantApp) {
5841 signingDetails = ((SharedUserSetting)obj).signatures.mSigningDetails;
5842 } else if (obj instanceof PackageSetting) {
5843 final PackageSetting ps = (PackageSetting) obj;
5844 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
5847 signingDetails = ps.signatures.mSigningDetails;
5855 case CERT_INPUT_RAW_X509:
5856 return signingDetails.hasCertificate(certificate);
5857 case CERT_INPUT_SHA256:
5858 return signingDetails.hasSha256Certificate(certificate);
5866 * If the database version for this type of package (internal storage or
5867 * external storage) is less than the version where package signatures
5868 * were updated, return true.
5870 private boolean isCompatSignatureUpdateNeeded(AndroidPackage pkg) {
5871 return isCompatSignatureUpdateNeeded(getSettingsVersionForPackage(pkg));
5874 private static boolean isCompatSignatureUpdateNeeded(VersionInfo ver) {
5875 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5878 private boolean isRecoverSignatureUpdateNeeded(AndroidPackage pkg) {
5879 return isRecoverSignatureUpdateNeeded(getSettingsVersionForPackage(pkg));
5882 private static boolean isRecoverSignatureUpdateNeeded(VersionInfo ver) {
5883 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5887 public List<String> getAllPackages() {
5888 final int callingUid = Binder.getCallingUid();
5889 final int callingUserId = UserHandle.getUserId(callingUid);
5890 synchronized (mLock) {
5891 if (canViewInstantApps(callingUid, callingUserId)) {
5892 return new ArrayList<>(mPackages.keySet());
5894 final String instantAppPkgName = getInstantAppPackageName(callingUid);
5895 final List<String> result = new ArrayList<>();
5896 if (instantAppPkgName != null) {
5897 // caller is an instant application; filter unexposed applications
5898 for (AndroidPackage pkg : mPackages.values()) {
5899 if (!pkg.isVisibleToInstantApps()) {
5902 result.add(pkg.getPackageName());
5905 // caller is a normal application; filter instant applications
5906 for (AndroidPackage pkg : mPackages.values()) {
5907 final PackageSetting ps = getPackageSetting(pkg.getPackageName());
5909 && ps.getInstantApp(callingUserId)
5910 && !mInstantAppRegistry.isInstantAccessGranted(
5911 callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
5914 result.add(pkg.getPackageName());
5922 * <em>IMPORTANT:</em> Not all packages returned by this method may be known
5923 * to the system. There are two conditions in which this may occur:
5925 * <li>The package is on adoptable storage and the device has been removed</li>
5926 * <li>The package is being removed and the internal structures are partially updated</li>
5928 * The second is an artifact of the current data structures and should be fixed. See
5929 * b/111075456 for one such instance.
5932 public String[] getPackagesForUid(int uid) {
5933 return getPackagesForUidInternal(uid, Binder.getCallingUid());
5936 private String[] getPackagesForUidInternal(int uid, int callingUid) {
5937 final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5938 final int userId = UserHandle.getUserId(uid);
5939 final int appId = UserHandle.getAppId(uid);
5941 synchronized (mLock) {
5942 final Object obj = mSettings.getSettingLPr(appId);
5943 if (obj instanceof SharedUserSetting) {
5944 if (isCallerInstantApp) {
5947 final SharedUserSetting sus = (SharedUserSetting) obj;
5948 final int N = sus.packages.size();
5949 String[] res = new String[N];
5950 final Iterator<PackageSetting> it = sus.packages.iterator();
5952 while (it.hasNext()) {
5953 PackageSetting ps = it.next();
5954 if (ps.getInstalled(userId)) {
5958 return ArrayUtils.trimToSize(res, i);
5959 } else if (obj instanceof PackageSetting) {
5960 final PackageSetting ps = (PackageSetting) obj;
5961 if (ps.getInstalled(userId)
5962 && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
5963 return new String[]{ps.name};
5971 public String getNameForUid(int uid) {
5972 final int callingUid = Binder.getCallingUid();
5973 if (getInstantAppPackageName(callingUid) != null) {
5976 final int appId = UserHandle.getAppId(uid);
5977 synchronized (mLock) {
5978 final Object obj = mSettings.getSettingLPr(appId);
5979 if (obj instanceof SharedUserSetting) {
5980 final SharedUserSetting sus = (SharedUserSetting) obj;
5981 return sus.name + ":" + sus.userId;
5982 } else if (obj instanceof PackageSetting) {
5983 final PackageSetting ps = (PackageSetting) obj;
5984 if (shouldFilterApplicationLocked(
5985 ps, callingUid, UserHandle.getUserId(callingUid))) {
5995 public String[] getNamesForUids(int[] uids) {
5996 if (uids == null || uids.length == 0) {
5999 final int callingUid = Binder.getCallingUid();
6000 if (getInstantAppPackageName(callingUid) != null) {
6003 final String[] names = new String[uids.length];
6004 synchronized (mLock) {
6005 for (int i = uids.length - 1; i >= 0; i--) {
6006 final int appId = UserHandle.getAppId(uids[i]);
6007 final Object obj = mSettings.getSettingLPr(appId);
6008 if (obj instanceof SharedUserSetting) {
6009 final SharedUserSetting sus = (SharedUserSetting) obj;
6010 names[i] = "shared:" + sus.name;
6011 } else if (obj instanceof PackageSetting) {
6012 final PackageSetting ps = (PackageSetting) obj;
6013 if (shouldFilterApplicationLocked(
6014 ps, callingUid, UserHandle.getUserId(callingUid))) {
6028 public int getUidForSharedUser(String sharedUserName) {
6029 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6032 if (sharedUserName == null) {
6036 synchronized (mLock) {
6037 SharedUserSetting suid;
6039 suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
6043 } catch (PackageManagerException ignore) {
6044 // can't happen, but, still need to catch it
6051 public int getFlagsForUid(int uid) {
6052 final int callingUid = Binder.getCallingUid();
6053 if (getInstantAppPackageName(callingUid) != null) {
6056 final int appId = UserHandle.getAppId(uid);
6057 synchronized (mLock) {
6058 final Object obj = mSettings.getSettingLPr(appId);
6059 if (obj instanceof SharedUserSetting) {
6060 final SharedUserSetting sus = (SharedUserSetting) obj;
6061 return sus.pkgFlags;
6062 } else if (obj instanceof PackageSetting) {
6063 final PackageSetting ps = (PackageSetting) obj;
6064 if (shouldFilterApplicationLocked(
6065 ps, callingUid, UserHandle.getUserId(callingUid))) {
6075 public int getPrivateFlagsForUid(int uid) {
6076 final int callingUid = Binder.getCallingUid();
6077 if (getInstantAppPackageName(callingUid) != null) {
6080 final int appId = UserHandle.getAppId(uid);
6081 synchronized (mLock) {
6082 final Object obj = mSettings.getSettingLPr(appId);
6083 if (obj instanceof SharedUserSetting) {
6084 final SharedUserSetting sus = (SharedUserSetting) obj;
6085 return sus.pkgPrivateFlags;
6086 } else if (obj instanceof PackageSetting) {
6087 final PackageSetting ps = (PackageSetting) obj;
6088 if (shouldFilterApplicationLocked(
6089 ps, callingUid, UserHandle.getUserId(callingUid))) {
6092 return ps.pkgPrivateFlags;
6099 public boolean isUidPrivileged(int uid) {
6100 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6103 final int appId = UserHandle.getAppId(uid);
6105 synchronized (mLock) {
6106 final Object obj = mSettings.getSettingLPr(appId);
6107 if (obj instanceof SharedUserSetting) {
6108 final SharedUserSetting sus = (SharedUserSetting) obj;
6109 final Iterator<PackageSetting> it = sus.packages.iterator();
6110 while (it.hasNext()) {
6111 if (it.next().isPrivileged()) {
6115 } else if (obj instanceof PackageSetting) {
6116 final PackageSetting ps = (PackageSetting) obj;
6117 return ps.isPrivileged();
6123 // NOTE: Can't remove due to unsupported app usage
6125 public String[] getAppOpPermissionPackages(String permName) {
6127 // Because this is accessed via the package manager service AIDL,
6128 // go through the permission manager service AIDL
6129 return mPermissionManagerService.getAppOpPermissionPackages(permName);
6130 } catch (RemoteException ignore) { }
6135 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
6136 int flags, int userId) {
6137 return resolveIntentInternal(intent, resolvedType, flags, 0 /*privateResolveFlags*/,
6138 userId, false, Binder.getCallingUid());
6142 * Normally instant apps can only be resolved when they're visible to the caller.
6143 * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
6144 * since we need to allow the system to start any installed application.
6146 private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType, int flags,
6147 @PrivateResolveFlags int privateResolveFlags, int userId, boolean resolveForStart,
6148 int filterCallingUid) {
6150 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
6152 if (!mUserManager.exists(userId)) return null;
6153 final int callingUid = Binder.getCallingUid();
6154 flags = updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart);
6155 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
6156 false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
6158 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6159 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
6160 flags, privateResolveFlags, filterCallingUid, userId, resolveForStart,
6161 true /*allowDynamicSplits*/);
6162 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6164 final ResolveInfo bestChoice =
6166 intent, resolvedType, flags, privateResolveFlags, query, userId);
6169 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6174 public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
6175 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
6176 throw new SecurityException(
6177 "findPersistentPreferredActivity can only be run by the system");
6179 if (!mUserManager.exists(userId)) {
6182 final int callingUid = Binder.getCallingUid();
6183 intent = updateIntentForResolve(intent);
6184 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
6185 final int flags = updateFlagsForResolve(
6186 0, userId, callingUid, false /*includeInstantApps*/);
6187 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6189 synchronized (mLock) {
6190 return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
6196 public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
6197 IntentFilter filter, int match, ComponentName activity) {
6198 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6201 final int userId = UserHandle.getCallingUserId();
6202 if (DEBUG_PREFERRED) {
6203 Log.v(TAG, "setLastChosenActivity intent=" + intent
6204 + " resolvedType=" + resolvedType
6206 + " filter=" + filter
6208 + " activity=" + activity);
6209 filter.dump(new PrintStreamPrinter(System.out), " ");
6211 intent.setComponent(null);
6212 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6214 // Find any earlier preferred or last chosen entries and nuke them
6215 findPreferredActivityNotLocked(
6216 intent, resolvedType, flags, query, 0, false, true, false, userId);
6217 // Add the new activity as the last chosen for this filter
6218 addPreferredActivityInternal(filter, match, null, activity, false, userId,
6219 "Setting last chosen");
6223 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
6224 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6227 final int userId = UserHandle.getCallingUserId();
6228 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
6229 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6231 return findPreferredActivityNotLocked(
6232 intent, resolvedType, flags, query, 0, false, false, false, userId);
6236 * Returns whether or not instant apps have been disabled remotely.
6238 private boolean areWebInstantAppsDisabled(int userId) {
6239 return mWebInstantAppsDisabled.get(userId);
6242 private boolean isInstantAppResolutionAllowed(
6243 Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6244 boolean skipPackageCheck) {
6245 if (mInstantAppResolverConnection == null) {
6248 if (mInstantAppInstallerActivity == null) {
6251 if (intent.getComponent() != null) {
6254 if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6257 if (!skipPackageCheck && intent.getPackage() != null) {
6260 if (!intent.isWebIntent()) {
6261 // for non web intents, we should not resolve externally if an app already exists to
6262 // handle it or if the caller didn't explicitly request it.
6263 if ((resolvedActivities != null && resolvedActivities.size() != 0)
6264 || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) == 0) {
6268 if (intent.getData() == null || TextUtils.isEmpty(intent.getData().getHost())) {
6270 } else if (areWebInstantAppsDisabled(userId)) {
6274 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6275 // Or if there's already an ephemeral app installed that handles the action
6276 synchronized (mLock) {
6277 final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6278 for (int n = 0; n < count; n++) {
6279 final ResolveInfo info = resolvedActivities.get(n);
6280 final String packageName = info.activityInfo.packageName;
6281 final PackageSetting ps = mSettings.mPackages.get(packageName);
6283 // only check domain verification status if the app is not a browser
6284 if (!info.handleAllWebDataURI) {
6285 // Try to get the status from User settings first
6286 final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6287 final int status = (int) (packedStatus >> 32);
6288 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6289 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6290 if (DEBUG_INSTANT) {
6291 Slog.v(TAG, "DENY instant app;"
6292 + " pkg: " + packageName + ", status: " + status);
6297 if (ps.getInstantApp(userId)) {
6298 if (DEBUG_INSTANT) {
6299 Slog.v(TAG, "DENY instant app installed;"
6300 + " pkg: " + packageName);
6307 // We've exhausted all ways to deny ephemeral application; let the system look for them.
6311 private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6312 Intent origIntent, String resolvedType, String callingPackage,
6313 @Nullable String callingFeatureId, boolean isRequesterInstantApp,
6314 Bundle verificationBundle, int userId) {
6315 final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6316 new InstantAppRequest(responseObj, origIntent, resolvedType,
6317 callingPackage, callingFeatureId, isRequesterInstantApp, userId, verificationBundle,
6318 false /*resolveForStart*/, responseObj.hostDigestPrefixSecure,
6319 responseObj.token));
6320 mHandler.sendMessage(msg);
6323 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6324 int flags, int privateResolveFlags, List<ResolveInfo> query, int userId) {
6325 if (query != null) {
6326 final int N = query.size();
6328 return query.get(0);
6330 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6331 // If there is more than one activity with the same priority,
6332 // then let the user decide between them.
6333 ResolveInfo r0 = query.get(0);
6334 ResolveInfo r1 = query.get(1);
6335 if (DEBUG_INTENT_MATCHING || debug) {
6336 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6337 + r1.activityInfo.name + "=" + r1.priority);
6339 // If the first activity has a higher priority, or a different
6340 // default, then it is always desirable to pick it.
6341 if (r0.priority != r1.priority
6342 || r0.preferredOrder != r1.preferredOrder
6343 || r0.isDefault != r1.isDefault) {
6344 return query.get(0);
6346 // If we have saved a preference for a preferred activity for
6347 // this Intent, use that.
6348 ResolveInfo ri = findPreferredActivityNotLocked(intent, resolvedType,
6349 flags, query, r0.priority, true, false, debug, userId);
6353 // If we have an ephemeral app, use it
6354 for (int i = 0; i < N; i++) {
6356 if (ri.activityInfo.applicationInfo.isInstantApp()) {
6357 final String packageName = ri.activityInfo.packageName;
6358 final PackageSetting ps = mSettings.mPackages.get(packageName);
6359 final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6360 final int status = (int)(packedStatus >> 32);
6361 if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6366 if ((privateResolveFlags
6367 & PackageManagerInternal.RESOLVE_NON_RESOLVER_ONLY) != 0) {
6370 ri = new ResolveInfo(mResolveInfo);
6371 ri.activityInfo = new ActivityInfo(ri.activityInfo);
6372 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6373 // If all of the options come from the same package, show the application's
6374 // label and icon instead of the generic resolver's.
6375 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6376 // and then throw away the ResolveInfo itself, meaning that the caller loses
6377 // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6378 // a fallback for this case; we only set the target package's resources on
6379 // the ResolveInfo, not the ActivityInfo.
6380 final String intentPackage = intent.getPackage();
6381 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6382 final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6383 ri.resolvePackageName = intentPackage;
6384 if (userNeedsBadging(userId)) {
6385 ri.noResourceId = true;
6387 ri.icon = appi.icon;
6389 ri.iconResourceId = appi.icon;
6390 ri.labelRes = appi.labelRes;
6392 ri.activityInfo.applicationInfo = new ApplicationInfo(
6393 ri.activityInfo.applicationInfo);
6395 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6396 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6398 // Make sure that the resolver is displayable in car mode
6399 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6400 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6408 * Return true if the given list is not empty and all of its contents have
6409 * an activityInfo with the given package name.
6411 private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6412 if (ArrayUtils.isEmpty(list)) {
6415 for (int i = 0, N = list.size(); i < N; i++) {
6416 final ResolveInfo ri = list.get(i);
6417 final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6418 if (ai == null || !packageName.equals(ai.packageName)) {
6426 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6427 int flags, List<ResolveInfo> query, boolean debug, int userId) {
6428 final int N = query.size();
6429 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6431 // Get the list of persistent preferred activities that handle the intent
6432 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6433 List<PersistentPreferredActivity> pprefs = ppir != null
6434 ? ppir.queryIntent(intent, resolvedType,
6435 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6438 if (pprefs != null && pprefs.size() > 0) {
6439 final int M = pprefs.size();
6440 for (int i=0; i<M; i++) {
6441 final PersistentPreferredActivity ppa = pprefs.get(i);
6442 if (DEBUG_PREFERRED || debug) {
6443 Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6444 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6445 + "\n component=" + ppa.mComponent);
6446 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6448 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6449 flags | MATCH_DISABLED_COMPONENTS, userId);
6450 if (DEBUG_PREFERRED || debug) {
6451 Slog.v(TAG, "Found persistent preferred activity:");
6453 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6455 Slog.v(TAG, " null");
6459 // This previously registered persistent preferred activity
6460 // component is no longer known. Ignore it and do NOT remove it.
6463 for (int j=0; j<N; j++) {
6464 final ResolveInfo ri = query.get(j);
6465 if (!ri.activityInfo.applicationInfo.packageName
6466 .equals(ai.applicationInfo.packageName)) {
6469 if (!ri.activityInfo.name.equals(ai.name)) {
6472 // Found a persistent preference that can handle the intent.
6473 if (DEBUG_PREFERRED || debug) {
6474 Slog.v(TAG, "Returning persistent preferred activity: " +
6475 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6484 private boolean isHomeIntent(Intent intent) {
6485 return ACTION_MAIN.equals(intent.getAction())
6486 && intent.hasCategory(CATEGORY_HOME)
6487 && intent.hasCategory(CATEGORY_DEFAULT);
6490 // TODO: handle preferred activities missing while user has amnesia
6491 /** <b>must not hold {@link #mLock}</b> */
6492 ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
6493 List<ResolveInfo> query, int priority, boolean always,
6494 boolean removeMatches, boolean debug, int userId) {
6495 if (Thread.holdsLock(mLock)) {
6496 Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
6497 + " is holding mLock", new Throwable());
6499 if (!mUserManager.exists(userId)) return null;
6500 final int callingUid = Binder.getCallingUid();
6501 // Do NOT hold the packages lock; this calls up into the settings provider which
6502 // could cause a deadlock.
6503 final boolean isDeviceProvisioned =
6504 android.provider.Settings.Global.getInt(mContext.getContentResolver(),
6505 android.provider.Settings.Global.DEVICE_PROVISIONED, 0) == 1;
6506 flags = updateFlagsForResolve(
6507 flags, userId, callingUid, false /*includeInstantApps*/);
6508 intent = updateIntentForResolve(intent);
6510 synchronized (mLock) {
6511 // Try to find a matching persistent preferred activity.
6512 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6515 // If a persistent preferred activity matched, use it.
6520 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6521 // Get the list of preferred activities that handle the intent
6522 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6523 List<PreferredActivity> prefs = pir != null
6524 ? pir.queryIntent(intent, resolvedType,
6525 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6528 if (prefs != null && prefs.size() > 0) {
6529 boolean changed = false;
6531 // First figure out how good the original match set is.
6532 // We will only allow preferred activities that came
6533 // from the same match quality.
6536 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6538 final int N = query.size();
6539 for (int j=0; j<N; j++) {
6540 final ResolveInfo ri = query.get(j);
6541 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6542 + ": 0x" + Integer.toHexString(match));
6543 if (ri.match > match) {
6548 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6549 + Integer.toHexString(match));
6551 match &= IntentFilter.MATCH_CATEGORY_MASK;
6552 final int M = prefs.size();
6553 for (int i=0; i<M; i++) {
6554 final PreferredActivity pa = prefs.get(i);
6555 if (DEBUG_PREFERRED || debug) {
6556 Slog.v(TAG, "Checking PreferredActivity ds="
6557 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6558 + "\n component=" + pa.mPref.mComponent);
6559 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6561 if (pa.mPref.mMatch != match) {
6562 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6563 + Integer.toHexString(pa.mPref.mMatch));
6566 // If it's not an "always" type preferred activity and that's what we're
6567 // looking for, skip it.
6568 if (always && !pa.mPref.mAlways) {
6569 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6572 final ActivityInfo ai = getActivityInfo(
6573 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6574 | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6576 if (DEBUG_PREFERRED || debug) {
6577 Slog.v(TAG, "Found preferred activity:");
6579 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6581 Slog.v(TAG, " null");
6584 final boolean excludeSetupWizardHomeActivity = isHomeIntent(intent)
6585 && !isDeviceProvisioned;
6587 // Do not remove launcher's preferred activity during SetupWizard
6588 // due to it may not install yet
6589 if (excludeSetupWizardHomeActivity) {
6593 // This previously registered preferred activity
6594 // component is no longer known. Most likely an update
6595 // to the app was installed and in the new version this
6596 // component no longer exists. Clean it up by removing
6597 // it from the preferred activities list, and skip it.
6598 Slog.w(TAG, "Removing dangling preferred activity: "
6599 + pa.mPref.mComponent);
6600 pir.removeFilter(pa);
6604 for (int j=0; j<N; j++) {
6605 final ResolveInfo ri = query.get(j);
6606 if (!ri.activityInfo.applicationInfo.packageName
6607 .equals(ai.applicationInfo.packageName)) {
6610 if (!ri.activityInfo.name.equals(ai.name)) {
6614 if (removeMatches) {
6615 pir.removeFilter(pa);
6617 if (DEBUG_PREFERRED) {
6618 Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6623 // Okay we found a previously set preferred or last chosen app.
6624 // If the result set is different from when this
6625 // was created, and is not a subset of the preferred set, we need to
6626 // clear it and re-ask the user their preference, if we're looking for
6627 // an "always" type entry.
6629 if (always && !pa.mPref.sameSet(query, excludeSetupWizardHomeActivity)) {
6630 if (pa.mPref.isSuperset(query, excludeSetupWizardHomeActivity)) {
6631 if (!excludeSetupWizardHomeActivity) {
6632 // some components of the set are no longer present in
6633 // the query, but the preferred activity can still be reused
6634 if (DEBUG_PREFERRED) {
6635 Slog.i(TAG, "Result set changed, but PreferredActivity"
6636 + " is still valid as only non-preferred"
6637 + " components were removed for " + intent
6638 + " type " + resolvedType);
6640 // remove obsolete components and re-add the up-to-date
6642 PreferredActivity freshPa = new PreferredActivity(pa,
6644 pa.mPref.discardObsoleteComponents(query),
6645 pa.mPref.mComponent,
6647 pir.removeFilter(pa);
6648 pir.addFilter(freshPa);
6651 if (DEBUG_PREFERRED) {
6652 Slog.i(TAG, "Do not remove preferred activity for launcher"
6653 + " during SetupWizard");
6658 "Result set changed, dropping preferred activity for "
6659 + intent + " type " + resolvedType);
6660 if (DEBUG_PREFERRED) {
6661 Slog.v(TAG, "Removing preferred activity since set changed "
6662 + pa.mPref.mComponent);
6664 pir.removeFilter(pa);
6665 // Re-add the filter as a "last chosen" entry (!always)
6666 PreferredActivity lastChosen = new PreferredActivity(
6667 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6668 pir.addFilter(lastChosen);
6674 // Yay! Either the set matched or we're looking for the last chosen
6675 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6676 + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6682 if (DEBUG_PREFERRED) {
6683 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6685 scheduleWritePackageRestrictionsLocked(userId);
6690 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6695 * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6698 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6700 mContext.enforceCallingOrSelfPermission(
6701 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6702 List<CrossProfileIntentFilter> matches =
6703 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6704 if (matches != null) {
6705 int size = matches.size();
6706 for (int i = 0; i < size; i++) {
6707 if (matches.get(i).getTargetUserId() == targetUserId) return true;
6710 if (intent.hasWebURI()) {
6711 // cross-profile app linking works only towards the parent.
6712 final int callingUid = Binder.getCallingUid();
6713 final UserInfo parent = getProfileParent(sourceUserId);
6714 if (parent == null) {
6717 synchronized (mLock) {
6718 int flags = updateFlagsForResolve(0, parent.id, callingUid,
6719 false /*includeInstantApps*/);
6720 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6721 intent, resolvedType, flags, sourceUserId, parent.id);
6722 return xpDomainInfo != null;
6728 private UserInfo getProfileParent(int userId) {
6729 final long identity = Binder.clearCallingIdentity();
6731 return mUserManager.getProfileParent(userId);
6733 Binder.restoreCallingIdentity(identity);
6737 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6738 String resolvedType, int userId) {
6739 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6740 if (resolver != null) {
6741 return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6747 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6748 String resolvedType, int flags, int userId) {
6750 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6752 return new ParceledListSlice<>(
6753 queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6755 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6760 * Returns the package name of the calling Uid if it's an instant app. If it isn't
6761 * instant, returns {@code null}.
6763 private String getInstantAppPackageName(int callingUid) {
6764 synchronized (mLock) {
6765 // If the caller is an isolated app use the owner's uid for the lookup.
6766 if (Process.isIsolated(callingUid)) {
6767 callingUid = mIsolatedOwners.get(callingUid);
6769 final int appId = UserHandle.getAppId(callingUid);
6770 final Object obj = mSettings.getSettingLPr(appId);
6771 if (obj instanceof PackageSetting) {
6772 final PackageSetting ps = (PackageSetting) obj;
6773 final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6774 return isInstantApp ? ps.pkg.getPackageName() : null;
6780 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6781 String resolvedType, int flags, int userId) {
6782 return queryIntentActivitiesInternal(
6783 intent, resolvedType, flags, 0 /*privateResolveFlags*/, Binder.getCallingUid(),
6784 userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
6787 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6788 String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags,
6789 int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits) {
6790 if (!mUserManager.exists(userId)) return Collections.emptyList();
6791 final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
6792 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
6793 false /* requireFullPermission */, false /* checkShell */,
6794 "query intent activities");
6795 final String pkgName = intent.getPackage();
6796 ComponentName comp = intent.getComponent();
6798 if (intent.getSelector() != null) {
6799 intent = intent.getSelector();
6800 comp = intent.getComponent();
6804 flags = updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart,
6805 comp != null || pkgName != null /*onlyExposedExplicitly*/);
6807 final List<ResolveInfo> list = new ArrayList<>(1);
6808 final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6810 // When specifying an explicit component, we prevent the activity from being
6811 // used when either 1) the calling package is normal and the activity is within
6812 // an ephemeral application or 2) the calling package is ephemeral and the
6813 // activity is not visible to ephemeral applications.
6814 final boolean matchInstantApp =
6815 (flags & PackageManager.MATCH_INSTANT) != 0;
6816 final boolean matchVisibleToInstantAppOnly =
6817 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6818 final boolean matchExplicitlyVisibleOnly =
6819 (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
6820 final boolean isCallerInstantApp =
6821 instantAppPkgName != null;
6822 final boolean isTargetSameInstantApp =
6823 comp.getPackageName().equals(instantAppPkgName);
6824 final boolean isTargetInstantApp =
6825 (ai.applicationInfo.privateFlags
6826 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6827 final boolean isTargetVisibleToInstantApp =
6828 (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
6829 final boolean isTargetExplicitlyVisibleToInstantApp =
6830 isTargetVisibleToInstantApp
6831 && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
6832 final boolean isTargetHiddenFromInstantApp =
6833 !isTargetVisibleToInstantApp
6834 || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
6835 final boolean blockResolution =
6836 !isTargetSameInstantApp
6837 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6838 || (matchVisibleToInstantAppOnly && isCallerInstantApp
6839 && isTargetHiddenFromInstantApp));
6840 if (!blockResolution) {
6841 final ResolveInfo ri = new ResolveInfo();
6842 ri.activityInfo = ai;
6847 List<ResolveInfo> result = applyPostResolutionFilter(
6848 list, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,
6854 boolean sortResult = false;
6855 boolean addInstant = false;
6856 List<ResolveInfo> result;
6857 synchronized (mLock) {
6858 if (pkgName == null) {
6859 List<CrossProfileIntentFilter> matchingFilters =
6860 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6861 // Check for results that need to skip the current profile.
6862 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
6863 resolvedType, flags, userId);
6864 if (xpResolveInfo != null) {
6865 List<ResolveInfo> xpResult = new ArrayList<>(1);
6866 xpResult.add(xpResolveInfo);
6867 return applyPostResolutionFilter(
6868 filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
6869 allowDynamicSplits, filterCallingUid, resolveForStart, userId, intent);
6872 // Check for results in the current profile.
6873 result = filterIfNotSystemUser(mComponentResolver.queryActivities(
6874 intent, resolvedType, flags, privateResolveFlags, userId), userId);
6875 addInstant = isInstantAppResolutionAllowed(intent, result, userId,
6876 false /*skipPackageCheck*/);
6877 // Check for cross profile results.
6878 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6879 xpResolveInfo = queryCrossProfileIntents(
6880 matchingFilters, intent, resolvedType, flags, userId,
6881 hasNonNegativePriorityResult);
6882 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6883 boolean isVisibleToUser = filterIfNotSystemUser(
6884 Collections.singletonList(xpResolveInfo), userId).size() > 0;
6885 if (isVisibleToUser) {
6886 result.add(xpResolveInfo);
6890 if (intent.hasWebURI()) {
6891 CrossProfileDomainInfo xpDomainInfo = null;
6892 final UserInfo parent = getProfileParent(userId);
6893 if (parent != null) {
6894 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6895 flags, userId, parent.id);
6897 if (xpDomainInfo != null) {
6898 if (xpResolveInfo != null) {
6899 // If we didn't remove it, the cross-profile ResolveInfo would be twice
6901 result.remove(xpResolveInfo);
6903 if (result.size() == 0 && !addInstant) {
6904 // No result in current profile, but found candidate in parent user.
6905 // And we are not going to add emphemeral app, so we can return the
6906 // result straight away.
6907 result.add(xpDomainInfo.resolveInfo);
6908 return applyPostResolutionFilter(result, instantAppPkgName,
6909 allowDynamicSplits, filterCallingUid, resolveForStart, userId,
6912 } else if (result.size() <= 1 && !addInstant) {
6913 // No result in parent user and <= 1 result in current profile, and we
6914 // are not going to add emphemeral app, so we can return the result without
6915 // further processing.
6916 return applyPostResolutionFilter(result, instantAppPkgName,
6917 allowDynamicSplits, filterCallingUid, resolveForStart, userId,
6920 // We have more than one candidate (combining results from current and parent
6921 // profile), so we need filtering and sorting.
6922 result = filterCandidatesWithDomainPreferredActivitiesLPr(
6923 intent, flags, result, xpDomainInfo, userId);
6927 final AndroidPackage pkg = mPackages.get(pkgName);
6930 result = filterIfNotSystemUser(mComponentResolver.queryActivities(
6931 intent, resolvedType, flags, pkg.getActivities(), userId), userId);
6933 if (result == null || result.size() == 0) {
6934 // the caller wants to resolve for a particular package; however, there
6935 // were no installed results, so, try to find an ephemeral result
6936 addInstant = isInstantAppResolutionAllowed(
6937 intent, null /*result*/, userId, true /*skipPackageCheck*/);
6938 if (result == null) {
6939 result = new ArrayList<>();
6945 String callingPkgName = getInstantAppPackageName(filterCallingUid);
6946 boolean isRequesterInstantApp = isInstantApp(callingPkgName, userId);
6947 result = maybeAddInstantAppInstaller(result, intent, resolvedType, flags, userId,
6948 resolveForStart, isRequesterInstantApp);
6951 Collections.sort(result, RESOLVE_PRIORITY_SORTER);
6953 return applyPostResolutionFilter(
6954 result, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,
6958 private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
6959 String resolvedType, int flags, int userId, boolean resolveForStart,
6960 boolean isRequesterInstantApp) {
6961 // first, check to see if we've got an instant app already installed
6962 final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
6963 ResolveInfo localInstantApp = null;
6964 boolean blockResolution = false;
6965 if (!alreadyResolvedLocally) {
6966 final List<ResolveInfo> instantApps = mComponentResolver.queryActivities(
6970 | PackageManager.GET_RESOLVED_FILTER
6971 | PackageManager.MATCH_INSTANT
6972 | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
6974 for (int i = instantApps.size() - 1; i >= 0; --i) {
6975 final ResolveInfo info = instantApps.get(i);
6976 final String packageName = info.activityInfo.packageName;
6977 final PackageSetting ps = mSettings.mPackages.get(packageName);
6978 if (ps.getInstantApp(userId)) {
6979 final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6980 final int status = (int)(packedStatus >> 32);
6981 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6982 // there's a local instant application installed, but, the user has
6983 // chosen to never use it; skip resolution and don't acknowledge
6984 // an instant application is even available
6985 if (DEBUG_INSTANT) {
6986 Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
6988 blockResolution = true;
6991 // we have a locally installed instant application; skip resolution
6992 // but acknowledge there's an instant application available
6993 if (DEBUG_INSTANT) {
6994 Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
6996 localInstantApp = info;
7002 // no app installed, let's see if one's available
7003 AuxiliaryResolveInfo auxiliaryResponse = null;
7004 if (!blockResolution) {
7005 if (localInstantApp == null) {
7006 // we don't have an instant app locally, resolve externally
7007 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
7008 String token = UUID.randomUUID().toString();
7009 InstantAppDigest digest = InstantAppResolver.parseDigest(intent);
7010 final InstantAppRequest requestObject = new InstantAppRequest(null /*responseObj*/,
7011 intent /*origIntent*/, resolvedType, null /*callingPackage*/,
7012 null /*callingFeatureId*/, isRequesterInstantApp, userId,
7013 null /*verificationBundle*/, resolveForStart,
7014 digest.getDigestPrefixSecure(), token);
7015 auxiliaryResponse = InstantAppResolver.doInstantAppResolutionPhaseOne(
7016 mInstantAppResolverConnection, requestObject);
7017 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7019 // we have an instant application locally, but, we can't admit that since
7020 // callers shouldn't be able to determine prior browsing. create a dummy
7021 // auxiliary response so the downstream code behaves as if there's an
7022 // instant application available externally. when it comes time to start
7023 // the instant application, we'll do the right thing.
7024 final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
7025 auxiliaryResponse = new AuxiliaryResolveInfo(null /* failureActivity */,
7026 ai.packageName, ai.longVersionCode, null /* splitName */);
7029 if (intent.isWebIntent() && auxiliaryResponse == null) {
7032 final PackageSetting ps = mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
7034 || !ps.readUserState(userId).isEnabled(mInstantAppInstallerActivity, 0)) {
7037 final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
7038 ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
7039 mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
7040 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7041 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7042 // add a non-generic filter
7043 ephemeralInstaller.filter = new IntentFilter();
7044 if (intent.getAction() != null) {
7045 ephemeralInstaller.filter.addAction(intent.getAction());
7047 if (intent.getData() != null && intent.getData().getPath() != null) {
7048 ephemeralInstaller.filter.addDataPath(
7049 intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
7051 ephemeralInstaller.isInstantAppAvailable = true;
7052 // make sure this resolver is the default
7053 ephemeralInstaller.isDefault = true;
7054 ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
7055 if (DEBUG_INSTANT) {
7056 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7059 result.add(ephemeralInstaller);
7063 private static class CrossProfileDomainInfo {
7064 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
7065 ResolveInfo resolveInfo;
7066 /* Best domain verification status of the activities found in the other profile */
7067 int bestDomainVerificationStatus;
7070 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
7071 String resolvedType, int flags, int sourceUserId, int parentUserId) {
7072 if (!mUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
7076 List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent,
7077 resolvedType, flags, 0, parentUserId);
7079 if (resultTargetUser == null || resultTargetUser.isEmpty()) {
7082 CrossProfileDomainInfo result = null;
7083 int size = resultTargetUser.size();
7084 for (int i = 0; i < size; i++) {
7085 ResolveInfo riTargetUser = resultTargetUser.get(i);
7086 // Intent filter verification is only for filters that specify a host. So don't return
7087 // those that handle all web uris.
7088 if (riTargetUser.handleAllWebDataURI) {
7091 String packageName = riTargetUser.activityInfo.packageName;
7092 PackageSetting ps = mSettings.mPackages.get(packageName);
7096 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
7097 int status = (int)(verificationState >> 32);
7098 if (result == null) {
7099 result = new CrossProfileDomainInfo();
7100 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
7101 sourceUserId, parentUserId);
7102 result.bestDomainVerificationStatus = status;
7104 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
7105 result.bestDomainVerificationStatus);
7108 // Don't consider matches with status NEVER across profiles.
7109 if (result != null && result.bestDomainVerificationStatus
7110 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7117 * Verification statuses are ordered from the worse to the best, except for
7118 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
7120 private int bestDomainVerificationStatus(int status1, int status2) {
7121 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7124 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7127 return (int) MathUtils.max(status1, status2);
7130 private boolean isUserEnabled(int userId) {
7131 long callingId = Binder.clearCallingIdentity();
7133 UserInfo userInfo = mUserManager.getUserInfo(userId);
7134 return userInfo != null && userInfo.isEnabled();
7136 Binder.restoreCallingIdentity(callingId);
7141 * Filter out activities with systemUserOnly flag set, when current user is not System.
7143 * @return filtered list
7145 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
7146 if (userId == UserHandle.USER_SYSTEM) {
7147 return resolveInfos;
7149 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7150 ResolveInfo info = resolveInfos.get(i);
7151 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
7152 resolveInfos.remove(i);
7155 return resolveInfos;
7159 * Filters out ephemeral activities.
7160 * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
7161 * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
7163 * @param resolveInfos The pre-filtered list of resolved activities
7164 * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
7167 * @return A filtered list of resolved activities.
7169 private List<ResolveInfo> applyPostResolutionFilter(@NonNull List<ResolveInfo> resolveInfos,
7170 String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
7171 boolean resolveForStart, int userId, Intent intent) {
7172 final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled(userId);
7173 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7174 final ResolveInfo info = resolveInfos.get(i);
7175 // remove locally resolved instant app web results when disabled
7176 if (info.isInstantAppAvailable && blockInstant) {
7177 resolveInfos.remove(i);
7180 // allow activities that are defined in the provided package
7181 if (allowDynamicSplits
7182 && info.activityInfo != null
7183 && info.activityInfo.splitName != null
7184 && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
7185 info.activityInfo.splitName)) {
7186 if (mInstantAppInstallerActivity == null) {
7187 if (DEBUG_INSTALL) {
7188 Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
7190 resolveInfos.remove(i);
7193 if (blockInstant && isInstantApp(info.activityInfo.packageName, userId)) {
7194 resolveInfos.remove(i);
7197 // requested activity is defined in a split that hasn't been installed yet.
7198 // add the installer to the resolve list
7199 if (DEBUG_INSTALL) {
7200 Slog.v(TAG, "Adding installer to the ResolveInfo list");
7202 final ResolveInfo installerInfo = new ResolveInfo(
7203 mInstantAppInstallerInfo);
7204 final ComponentName installFailureActivity = findInstallFailureActivity(
7205 info.activityInfo.packageName, filterCallingUid, userId);
7206 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7207 installFailureActivity,
7208 info.activityInfo.packageName,
7209 info.activityInfo.applicationInfo.longVersionCode,
7210 info.activityInfo.splitName);
7211 // add a non-generic filter
7212 installerInfo.filter = new IntentFilter();
7214 // This resolve info may appear in the chooser UI, so let us make it
7215 // look as the one it replaces as far as the user is concerned which
7216 // requires loading the correct label and icon for the resolve info.
7217 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7218 installerInfo.labelRes = info.resolveLabelResId();
7219 installerInfo.icon = info.resolveIconResId();
7220 installerInfo.isInstantAppAvailable = true;
7221 resolveInfos.set(i, installerInfo);
7224 // caller is a full app, don't need to apply any other filtering
7225 if (ephemeralPkgName == null) {
7227 } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
7228 // caller is same app; don't need to apply any other filtering
7230 } else if (resolveForStart
7231 && (intent.isWebIntent()
7232 || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0)
7233 && intent.getPackage() == null
7234 && intent.getComponent() == null) {
7235 // ephemeral apps can launch other ephemeral apps indirectly
7238 // allow activities that have been explicitly exposed to ephemeral apps
7239 final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
7241 && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7244 resolveInfos.remove(i);
7246 return resolveInfos;
7250 * Returns the activity component that can handle install failures.
7251 * <p>By default, the instant application installer handles failures. However, an
7252 * application may want to handle failures on its own. Applications do this by
7253 * creating an activity with an intent filter that handles the action
7254 * {@link Intent#ACTION_INSTALL_FAILURE}.
7256 private @Nullable ComponentName findInstallFailureActivity(
7257 String packageName, int filterCallingUid, int userId) {
7258 final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
7259 failureActivityIntent.setPackage(packageName);
7260 // IMPORTANT: disallow dynamic splits to avoid an infinite loop
7261 final List<ResolveInfo> result = queryIntentActivitiesInternal(
7262 failureActivityIntent, null /*resolvedType*/, 0 /*flags*/,
7263 0 /*privateResolveFlags*/, filterCallingUid, userId, false /*resolveForStart*/,
7264 false /*allowDynamicSplits*/);
7265 final int NR = result.size();
7267 for (int i = 0; i < NR; i++) {
7268 final ResolveInfo info = result.get(i);
7269 if (info.activityInfo.splitName != null) {
7272 return new ComponentName(packageName, info.activityInfo.name);
7279 * @param resolveInfos list of resolve infos in descending priority order
7280 * @return if the list contains a resolve info with non-negative priority
7282 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
7283 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
7286 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
7287 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
7289 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
7291 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7292 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
7296 final ArrayList<ResolveInfo> result = new ArrayList<>();
7297 final ArrayList<ResolveInfo> alwaysList = new ArrayList<>();
7298 final ArrayList<ResolveInfo> undefinedList = new ArrayList<>();
7299 final ArrayList<ResolveInfo> alwaysAskList = new ArrayList<>();
7300 final ArrayList<ResolveInfo> neverList = new ArrayList<>();
7301 final ArrayList<ResolveInfo> matchAllList = new ArrayList<>();
7303 synchronized (mLock) {
7304 final int count = candidates.size();
7305 // First, try to use linked apps. Partition the candidates into four lists:
7306 // one for the final results, one for the "do not use ever", one for "undefined status"
7307 // and finally one for "browser app type".
7308 for (int n=0; n<count; n++) {
7309 ResolveInfo info = candidates.get(n);
7310 String packageName = info.activityInfo.packageName;
7311 PackageSetting ps = mSettings.mPackages.get(packageName);
7313 // Add to the special match all list (Browser use case)
7314 if (info.handleAllWebDataURI) {
7315 matchAllList.add(info);
7318 // Try to get the status from User settings first
7319 long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7320 int status = (int)(packedStatus >> 32);
7321 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7322 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
7323 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7324 Slog.i(TAG, " + always: " + info.activityInfo.packageName
7325 + " : linkgen=" + linkGeneration);
7327 // Use link-enabled generation as preferredOrder, i.e.
7328 // prefer newly-enabled over earlier-enabled.
7329 info.preferredOrder = linkGeneration;
7330 alwaysList.add(info);
7331 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7332 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7333 Slog.i(TAG, " + never: " + info.activityInfo.packageName);
7335 neverList.add(info);
7336 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7337 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7338 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName);
7340 alwaysAskList.add(info);
7341 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7342 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7343 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7344 Slog.i(TAG, " + ask: " + info.activityInfo.packageName);
7346 undefinedList.add(info);
7351 // We'll want to include browser possibilities in a few cases
7352 boolean includeBrowser = false;
7354 // First try to add the "always" resolution(s) for the current user, if any
7355 if (alwaysList.size() > 0) {
7356 result.addAll(alwaysList);
7358 // Add all undefined apps as we want them to appear in the disambiguation dialog.
7359 result.addAll(undefinedList);
7360 // Maybe add one for the other profile.
7361 if (xpDomainInfo != null && (
7362 xpDomainInfo.bestDomainVerificationStatus
7363 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7364 result.add(xpDomainInfo.resolveInfo);
7366 includeBrowser = true;
7369 // The presence of any 'always ask' alternatives means we'll also offer browsers.
7370 // If there were 'always' entries their preferred order has been set, so we also
7371 // back that off to make the alternatives equivalent
7372 if (alwaysAskList.size() > 0) {
7373 for (ResolveInfo i : result) {
7374 i.preferredOrder = 0;
7376 result.addAll(alwaysAskList);
7377 includeBrowser = true;
7380 if (includeBrowser) {
7381 // Also add browsers (all of them or only the default one)
7382 if (DEBUG_DOMAIN_VERIFICATION) {
7383 Slog.v(TAG, " ...including browsers in candidate set");
7385 if ((matchFlags & MATCH_ALL) != 0) {
7386 result.addAll(matchAllList);
7388 // Browser/generic handling case. If there's a default browser, go straight
7389 // to that (but only if there is no other higher-priority match).
7390 final String defaultBrowserPackageName =
7391 mPermissionManager.getDefaultBrowser(userId);
7392 int maxMatchPrio = 0;
7393 ResolveInfo defaultBrowserMatch = null;
7394 final int numCandidates = matchAllList.size();
7395 for (int n = 0; n < numCandidates; n++) {
7396 ResolveInfo info = matchAllList.get(n);
7397 // track the highest overall match priority...
7398 if (info.priority > maxMatchPrio) {
7399 maxMatchPrio = info.priority;
7401 // ...and the highest-priority default browser match
7402 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7403 if (defaultBrowserMatch == null
7404 || (defaultBrowserMatch.priority < info.priority)) {
7406 Slog.v(TAG, "Considering default browser match " + info);
7408 defaultBrowserMatch = info;
7412 if (defaultBrowserMatch != null
7413 && defaultBrowserMatch.priority >= maxMatchPrio
7414 && !TextUtils.isEmpty(defaultBrowserPackageName))
7417 Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7419 result.add(defaultBrowserMatch);
7421 result.addAll(matchAllList);
7425 // If there is nothing selected, add all candidates and remove the ones that the user
7426 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7427 if (result.size() == 0) {
7428 result.addAll(candidates);
7429 result.removeAll(neverList);
7433 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7434 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7436 for (ResolveInfo info : result) {
7437 Slog.v(TAG, " + " + info.activityInfo);
7443 // Returns a packed value as a long:
7445 // high 'int'-sized word: link status: undefined/ask/never/always.
7446 // low 'int'-sized word: relative priority among 'always' results.
7447 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7448 long result = ps.getDomainVerificationStatusForUser(userId);
7449 // if none available, get the master status
7450 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7451 if (ps.getIntentFilterVerificationInfo() != null) {
7452 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7458 private ResolveInfo querySkipCurrentProfileIntents(
7459 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7460 int flags, int sourceUserId) {
7461 if (matchingFilters != null) {
7462 int size = matchingFilters.size();
7463 for (int i = 0; i < size; i ++) {
7464 CrossProfileIntentFilter filter = matchingFilters.get(i);
7465 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7466 // Checking if there are activities in the target user that can handle the
7468 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7469 resolvedType, flags, sourceUserId);
7470 if (resolveInfo != null) {
7479 // Return matching ResolveInfo in target user if any.
7480 private ResolveInfo queryCrossProfileIntents(
7481 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7482 int flags, int sourceUserId, boolean matchInCurrentProfile) {
7483 if (matchingFilters != null) {
7484 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7485 // match the same intent. For performance reasons, it is better not to
7486 // run queryIntent twice for the same userId
7487 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7488 int size = matchingFilters.size();
7489 for (int i = 0; i < size; i++) {
7490 CrossProfileIntentFilter filter = matchingFilters.get(i);
7491 int targetUserId = filter.getTargetUserId();
7492 boolean skipCurrentProfile =
7493 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7494 boolean skipCurrentProfileIfNoMatchFound =
7495 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7496 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7497 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7498 // Checking if there are activities in the target user that can handle the
7500 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7501 resolvedType, flags, sourceUserId);
7502 if (resolveInfo != null) return resolveInfo;
7503 alreadyTriedUserIds.put(targetUserId, true);
7511 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7512 * will forward the intent to the filter's target user.
7513 * Otherwise, returns null.
7515 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7516 String resolvedType, int flags, int sourceUserId) {
7517 int targetUserId = filter.getTargetUserId();
7518 List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent,
7519 resolvedType, flags, 0, targetUserId);
7520 if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7521 // If all the matches in the target profile are suspended, return null.
7522 for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7523 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7524 & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7525 return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7533 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7534 int sourceUserId, int targetUserId) {
7535 ResolveInfo forwardingResolveInfo = new ResolveInfo();
7536 long ident = Binder.clearCallingIdentity();
7537 boolean targetIsProfile;
7539 targetIsProfile = mUserManager.getUserInfo(targetUserId).isManagedProfile();
7541 Binder.restoreCallingIdentity(ident);
7544 if (targetIsProfile) {
7545 className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7547 className = FORWARD_INTENT_TO_PARENT;
7549 ComponentName forwardingActivityComponentName = new ComponentName(
7550 mAndroidApplication.packageName, className);
7551 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7553 if (!targetIsProfile) {
7554 forwardingActivityInfo.showUserIcon = targetUserId;
7555 forwardingResolveInfo.noResourceId = true;
7557 forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7558 forwardingResolveInfo.priority = 0;
7559 forwardingResolveInfo.preferredOrder = 0;
7560 forwardingResolveInfo.match = 0;
7561 forwardingResolveInfo.isDefault = true;
7562 forwardingResolveInfo.filter = filter;
7563 forwardingResolveInfo.targetUserId = targetUserId;
7564 return forwardingResolveInfo;
7568 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7569 Intent[] specifics, String[] specificTypes, Intent intent,
7570 String resolvedType, int flags, int userId) {
7571 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7572 specificTypes, intent, resolvedType, flags, userId));
7575 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7576 Intent[] specifics, String[] specificTypes, Intent intent,
7577 String resolvedType, int flags, int userId) {
7578 if (!mUserManager.exists(userId)) return Collections.emptyList();
7579 final int callingUid = Binder.getCallingUid();
7580 flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/);
7581 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7582 false /*requireFullPermission*/, false /*checkShell*/,
7583 "query intent activity options");
7584 final String resultsAction = intent.getAction();
7586 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7587 | PackageManager.GET_RESOLVED_FILTER, userId);
7589 if (DEBUG_INTENT_MATCHING) {
7590 Log.v(TAG, "Query " + intent + ": " + results);
7593 int specificsPos = 0;
7596 // todo: note that the algorithm used here is O(N^2). This
7597 // isn't a problem in our current environment, but if we start running
7598 // into situations where we have more than 5 or 10 matches then this
7599 // should probably be changed to something smarter...
7601 // First we go through and resolve each of the specific items
7602 // that were supplied, taking care of removing any corresponding
7603 // duplicate items in the generic resolve list.
7604 if (specifics != null) {
7605 for (int i=0; i<specifics.length; i++) {
7606 final Intent sintent = specifics[i];
7607 if (sintent == null) {
7611 if (DEBUG_INTENT_MATCHING) {
7612 Log.v(TAG, "Specific #" + i + ": " + sintent);
7615 String action = sintent.getAction();
7616 if (resultsAction != null && resultsAction.equals(action)) {
7617 // If this action was explicitly requested, then don't
7618 // remove things that have it.
7622 ResolveInfo ri = null;
7623 ActivityInfo ai = null;
7625 ComponentName comp = sintent.getComponent();
7629 specificTypes != null ? specificTypes[i] : null,
7634 if (ri == mResolveInfo) {
7635 // ACK! Must do something better with this.
7637 ai = ri.activityInfo;
7638 comp = new ComponentName(ai.applicationInfo.packageName,
7641 ai = getActivityInfo(comp, flags, userId);
7647 // Look for any generic query activities that are duplicates
7648 // of this specific one, and remove them from the results.
7649 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7652 for (j=specificsPos; j<N; j++) {
7653 ResolveInfo sri = results.get(j);
7654 if ((sri.activityInfo.name.equals(comp.getClassName())
7655 && sri.activityInfo.applicationInfo.packageName.equals(
7656 comp.getPackageName()))
7657 || (action != null && sri.filter.matchAction(action))) {
7659 if (DEBUG_INTENT_MATCHING) Log.v(
7660 TAG, "Removing duplicate item from " + j
7661 + " due to specific " + specificsPos);
7670 // Add this specific item to its proper place.
7672 ri = new ResolveInfo();
7673 ri.activityInfo = ai;
7675 results.add(specificsPos, ri);
7676 ri.specificIndex = i;
7681 // Now we go through the remaining generic results and remove any
7682 // duplicate actions that are found here.
7684 for (int i=specificsPos; i<N-1; i++) {
7685 final ResolveInfo rii = results.get(i);
7686 if (rii.filter == null) {
7690 // Iterate over all of the actions of this result's intent
7691 // filter... typically this should be just one.
7692 final Iterator<String> it = rii.filter.actionsIterator();
7696 while (it.hasNext()) {
7697 final String action = it.next();
7698 if (resultsAction != null && resultsAction.equals(action)) {
7699 // If this action was explicitly requested, then don't
7700 // remove things that have it.
7703 for (int j=i+1; j<N; j++) {
7704 final ResolveInfo rij = results.get(j);
7705 if (rij.filter != null && rij.filter.hasAction(action)) {
7707 if (DEBUG_INTENT_MATCHING) Log.v(
7708 TAG, "Removing duplicate item from " + j
7709 + " due to action " + action + " at " + i);
7716 // If the caller didn't request filter information, drop it now
7717 // so we don't have to marshall/unmarshall it.
7718 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7723 // Filter out the caller activity if so requested.
7724 if (caller != null) {
7726 for (int i=0; i<N; i++) {
7727 ActivityInfo ainfo = results.get(i).activityInfo;
7728 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7729 && caller.getClassName().equals(ainfo.name)) {
7736 // If the caller didn't request filter information,
7737 // drop them now so we don't have to
7738 // marshall/unmarshall it.
7739 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7741 for (int i=0; i<N; i++) {
7742 results.get(i).filter = null;
7746 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7751 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7752 String resolvedType, int flags, int userId) {
7753 return new ParceledListSlice<>(
7754 queryIntentReceiversInternal(intent, resolvedType, flags, userId,
7755 false /*allowDynamicSplits*/));
7758 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7759 String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
7760 if (!mUserManager.exists(userId)) return Collections.emptyList();
7761 final int callingUid = Binder.getCallingUid();
7762 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7763 false /*requireFullPermission*/, false /*checkShell*/,
7764 "query intent receivers");
7765 final String instantAppPkgName = getInstantAppPackageName(callingUid);
7766 flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/);
7767 ComponentName comp = intent.getComponent();
7769 if (intent.getSelector() != null) {
7770 intent = intent.getSelector();
7771 comp = intent.getComponent();
7775 final List<ResolveInfo> list = new ArrayList<>(1);
7776 final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7778 // When specifying an explicit component, we prevent the activity from being
7779 // used when either 1) the calling package is normal and the activity is within
7780 // an instant application or 2) the calling package is ephemeral and the
7781 // activity is not visible to instant applications.
7782 final boolean matchInstantApp =
7783 (flags & PackageManager.MATCH_INSTANT) != 0;
7784 final boolean matchVisibleToInstantAppOnly =
7785 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7786 final boolean matchExplicitlyVisibleOnly =
7787 (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7788 final boolean isCallerInstantApp =
7789 instantAppPkgName != null;
7790 final boolean isTargetSameInstantApp =
7791 comp.getPackageName().equals(instantAppPkgName);
7792 final boolean isTargetInstantApp =
7793 (ai.applicationInfo.privateFlags
7794 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7795 final boolean isTargetVisibleToInstantApp =
7796 (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7797 final boolean isTargetExplicitlyVisibleToInstantApp =
7798 isTargetVisibleToInstantApp
7799 && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7800 final boolean isTargetHiddenFromInstantApp =
7801 !isTargetVisibleToInstantApp
7802 || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7803 final boolean blockResolution =
7804 !isTargetSameInstantApp
7805 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7806 || (matchVisibleToInstantAppOnly && isCallerInstantApp
7807 && isTargetHiddenFromInstantApp));
7808 if (!blockResolution) {
7809 ResolveInfo ri = new ResolveInfo();
7810 ri.activityInfo = ai;
7814 return applyPostResolutionFilter(
7815 list, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
7820 synchronized (mLock) {
7821 String pkgName = intent.getPackage();
7822 if (pkgName == null) {
7823 final List<ResolveInfo> result =
7824 mComponentResolver.queryReceivers(intent, resolvedType, flags, userId);
7825 if (result == null) {
7826 return Collections.emptyList();
7828 return applyPostResolutionFilter(
7829 result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
7832 final AndroidPackage pkg = mPackages.get(pkgName);
7834 final List<ResolveInfo> result = mComponentResolver.queryReceivers(
7835 intent, resolvedType, flags, pkg.getReceivers(), userId);
7836 if (result == null) {
7837 return Collections.emptyList();
7839 return applyPostResolutionFilter(
7840 result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
7843 return Collections.emptyList();
7848 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7849 final int callingUid = Binder.getCallingUid();
7850 return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
7853 private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7854 int userId, int callingUid) {
7855 if (!mUserManager.exists(userId)) return null;
7856 flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/);
7857 List<ResolveInfo> query = queryIntentServicesInternal(
7858 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7859 if (query != null) {
7860 if (query.size() >= 1) {
7861 // If there is more than one service with the same priority,
7862 // just arbitrarily pick the first one.
7863 return query.get(0);
7870 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7871 String resolvedType, int flags, int userId) {
7872 final int callingUid = Binder.getCallingUid();
7873 return new ParceledListSlice<>(queryIntentServicesInternal(
7874 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7877 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7878 String resolvedType, int flags, int userId, int callingUid,
7879 boolean includeInstantApps) {
7880 if (!mUserManager.exists(userId)) return Collections.emptyList();
7881 mPermissionManager.enforceCrossUserOrProfilePermission(callingUid,
7883 false /*requireFullPermission*/,
7884 false /*checkShell*/,
7885 "query intent receivers");
7886 final String instantAppPkgName = getInstantAppPackageName(callingUid);
7887 flags = updateFlagsForResolve(flags, userId, callingUid, includeInstantApps);
7888 ComponentName comp = intent.getComponent();
7890 if (intent.getSelector() != null) {
7891 intent = intent.getSelector();
7892 comp = intent.getComponent();
7896 final List<ResolveInfo> list = new ArrayList<>(1);
7897 final ServiceInfo si = getServiceInfo(comp, flags, userId);
7899 // When specifying an explicit component, we prevent the service from being
7900 // used when either 1) the service is in an instant application and the
7901 // caller is not the same instant application or 2) the calling package is
7902 // ephemeral and the activity is not visible to ephemeral applications.
7903 final boolean matchInstantApp =
7904 (flags & PackageManager.MATCH_INSTANT) != 0;
7905 final boolean matchVisibleToInstantAppOnly =
7906 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7907 final boolean isCallerInstantApp =
7908 instantAppPkgName != null;
7909 final boolean isTargetSameInstantApp =
7910 comp.getPackageName().equals(instantAppPkgName);
7911 final boolean isTargetInstantApp =
7912 (si.applicationInfo.privateFlags
7913 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7914 final boolean isTargetHiddenFromInstantApp =
7915 (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7916 final boolean blockResolution =
7917 !isTargetSameInstantApp
7918 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7919 || (matchVisibleToInstantAppOnly && isCallerInstantApp
7920 && isTargetHiddenFromInstantApp));
7921 if (!blockResolution) {
7922 final ResolveInfo ri = new ResolveInfo();
7923 ri.serviceInfo = si;
7931 synchronized (mLock) {
7932 String pkgName = intent.getPackage();
7933 if (pkgName == null) {
7934 final List<ResolveInfo> resolveInfos = mComponentResolver.queryServices(intent,
7935 resolvedType, flags, userId);
7936 if (resolveInfos == null) {
7937 return Collections.emptyList();
7939 return applyPostServiceResolutionFilter(
7943 final AndroidPackage pkg = mPackages.get(pkgName);
7945 final List<ResolveInfo> resolveInfos = mComponentResolver.queryServices(intent,
7946 resolvedType, flags, pkg.getServices(),
7948 if (resolveInfos == null) {
7949 return Collections.emptyList();
7951 return applyPostServiceResolutionFilter(
7955 return Collections.emptyList();
7959 private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7960 String instantAppPkgName) {
7961 if (instantAppPkgName == null) {
7962 return resolveInfos;
7964 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7965 final ResolveInfo info = resolveInfos.get(i);
7966 final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7967 // allow services that are defined in the provided package
7968 if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7969 if (info.serviceInfo.splitName != null
7970 && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7971 info.serviceInfo.splitName)) {
7972 // requested service is defined in a split that hasn't been installed yet.
7973 // add the installer to the resolve list
7974 if (DEBUG_INSTANT) {
7975 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7977 final ResolveInfo installerInfo = new ResolveInfo(
7978 mInstantAppInstallerInfo);
7979 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7980 null /* installFailureActivity */,
7981 info.serviceInfo.packageName,
7982 info.serviceInfo.applicationInfo.longVersionCode,
7983 info.serviceInfo.splitName);
7984 // add a non-generic filter
7985 installerInfo.filter = new IntentFilter();
7986 // load resources from the correct package
7987 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7988 resolveInfos.set(i, installerInfo);
7992 // allow services that have been explicitly exposed to ephemeral apps
7994 && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7997 resolveInfos.remove(i);
7999 return resolveInfos;
8003 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
8004 String resolvedType, int flags, int userId) {
8005 return new ParceledListSlice<>(
8006 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
8009 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
8010 Intent intent, String resolvedType, int flags, int userId) {
8011 if (!mUserManager.exists(userId)) return Collections.emptyList();
8012 final int callingUid = Binder.getCallingUid();
8013 final String instantAppPkgName = getInstantAppPackageName(callingUid);
8014 flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/);
8015 ComponentName comp = intent.getComponent();
8017 if (intent.getSelector() != null) {
8018 intent = intent.getSelector();
8019 comp = intent.getComponent();
8023 final List<ResolveInfo> list = new ArrayList<>(1);
8024 final ProviderInfo pi = getProviderInfo(comp, flags, userId);
8026 // When specifying an explicit component, we prevent the provider from being
8027 // used when either 1) the provider is in an instant application and the
8028 // caller is not the same instant application or 2) the calling package is an
8029 // instant application and the provider is not visible to instant applications.
8030 final boolean matchInstantApp =
8031 (flags & PackageManager.MATCH_INSTANT) != 0;
8032 final boolean matchVisibleToInstantAppOnly =
8033 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8034 final boolean isCallerInstantApp =
8035 instantAppPkgName != null;
8036 final boolean isTargetSameInstantApp =
8037 comp.getPackageName().equals(instantAppPkgName);
8038 final boolean isTargetInstantApp =
8039 (pi.applicationInfo.privateFlags
8040 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8041 final boolean isTargetHiddenFromInstantApp =
8042 (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8043 final boolean blockResolution =
8044 !isTargetSameInstantApp
8045 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8046 || (matchVisibleToInstantAppOnly && isCallerInstantApp
8047 && isTargetHiddenFromInstantApp));
8048 if (!blockResolution) {
8049 final ResolveInfo ri = new ResolveInfo();
8050 ri.providerInfo = pi;
8058 synchronized (mLock) {
8059 String pkgName = intent.getPackage();
8060 if (pkgName == null) {
8061 final List<ResolveInfo> resolveInfos = mComponentResolver.queryProviders(intent,
8062 resolvedType, flags, userId);
8063 if (resolveInfos == null) {
8064 return Collections.emptyList();
8066 return applyPostContentProviderResolutionFilter(
8070 final AndroidPackage pkg = mPackages.get(pkgName);
8072 final List<ResolveInfo> resolveInfos = mComponentResolver.queryProviders(intent,
8073 resolvedType, flags,
8074 pkg.getProviders(), userId);
8075 if (resolveInfos == null) {
8076 return Collections.emptyList();
8078 return applyPostContentProviderResolutionFilter(
8082 return Collections.emptyList();
8086 private List<ResolveInfo> applyPostContentProviderResolutionFilter(
8087 List<ResolveInfo> resolveInfos, String instantAppPkgName) {
8088 if (instantAppPkgName == null) {
8089 return resolveInfos;
8091 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8092 final ResolveInfo info = resolveInfos.get(i);
8093 final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
8094 // allow providers that are defined in the provided package
8095 if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
8096 if (info.providerInfo.splitName != null
8097 && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
8098 info.providerInfo.splitName)) {
8099 // requested provider is defined in a split that hasn't been installed yet.
8100 // add the installer to the resolve list
8101 if (DEBUG_INSTANT) {
8102 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8104 final ResolveInfo installerInfo = new ResolveInfo(
8105 mInstantAppInstallerInfo);
8106 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8107 null /*failureActivity*/,
8108 info.providerInfo.packageName,
8109 info.providerInfo.applicationInfo.longVersionCode,
8110 info.providerInfo.splitName);
8111 // add a non-generic filter
8112 installerInfo.filter = new IntentFilter();
8113 // load resources from the correct package
8114 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8115 resolveInfos.set(i, installerInfo);
8119 // allow providers that have been explicitly exposed to instant applications
8121 && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8124 resolveInfos.remove(i);
8126 return resolveInfos;
8130 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
8131 final int callingUid = Binder.getCallingUid();
8132 if (getInstantAppPackageName(callingUid) != null) {
8133 return ParceledListSlice.emptyList();
8135 if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
8136 flags = updateFlagsForPackage(flags, userId);
8137 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8138 final boolean listApex = (flags & MATCH_APEX) != 0;
8139 final boolean listFactory = (flags & MATCH_FACTORY_ONLY) != 0;
8141 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
8142 false /* requireFullPermission */, false /* checkShell */,
8143 "get installed packages");
8146 synchronized (mLock) {
8147 ArrayList<PackageInfo> list;
8148 if (listUninstalled) {
8149 list = new ArrayList<>(mSettings.mPackages.size());
8150 for (PackageSetting ps : mSettings.mPackages.values()) {
8151 if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8154 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
8157 final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8163 list = new ArrayList<>(mPackages.size());
8164 for (AndroidPackage p : mPackages.values()) {
8165 final PackageSetting ps = getPackageSetting(p.getPackageName());
8166 if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8169 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
8172 final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8180 list.addAll(mApexManager.getFactoryPackages());
8182 list.addAll(mApexManager.getActivePackages());
8184 if (listUninstalled) {
8185 list.addAll(mApexManager.getInactivePackages());
8188 return new ParceledListSlice<>(list);
8192 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
8193 String[] permissions, boolean[] tmp, int flags, int userId) {
8195 final PermissionsState permissionsState = ps.getPermissionsState();
8196 for (int i=0; i<permissions.length; i++) {
8197 final String permission = permissions[i];
8198 if (permissionsState.hasPermission(permission, userId)) {
8205 if (numMatch == 0) {
8208 final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8210 // The above might return null in cases of uninstalled apps or install-state
8211 // skew across users/profiles.
8213 if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
8214 if (numMatch == permissions.length) {
8215 pi.requestedPermissions = permissions;
8217 pi.requestedPermissions = new String[numMatch];
8219 for (int i=0; i<permissions.length; i++) {
8221 pi.requestedPermissions[numMatch] = permissions[i];
8232 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
8233 String[] permissions, int flags, int userId) {
8234 if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
8235 flags = updateFlagsForPackage(flags, userId);
8236 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8237 true /* requireFullPermission */, false /* checkShell */,
8238 "get packages holding permissions");
8239 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8242 synchronized (mLock) {
8243 ArrayList<PackageInfo> list = new ArrayList<>();
8244 boolean[] tmpBools = new boolean[permissions.length];
8245 if (listUninstalled) {
8246 for (PackageSetting ps : mSettings.mPackages.values()) {
8247 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8251 for (AndroidPackage pkg : mPackages.values()) {
8252 PackageSetting ps = getPackageSetting(pkg.getPackageName());
8254 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8260 return new ParceledListSlice<>(list);
8265 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
8266 final int callingUid = Binder.getCallingUid();
8267 return new ParceledListSlice<>(
8268 getInstalledApplicationsListInternal(flags, userId, callingUid));
8271 private List<ApplicationInfo> getInstalledApplicationsListInternal(int flags, int userId,
8273 if (getInstantAppPackageName(callingUid) != null) {
8274 return Collections.emptyList();
8276 if (!mUserManager.exists(userId)) return Collections.emptyList();
8277 flags = updateFlagsForApplication(flags, userId);
8278 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8280 mPermissionManager.enforceCrossUserPermission(
8283 false /* requireFullPermission */,
8284 false /* checkShell */,
8285 "get installed application info");
8288 synchronized (mLock) {
8289 ArrayList<ApplicationInfo> list;
8290 if (listUninstalled) {
8291 list = new ArrayList<>(mSettings.mPackages.size());
8292 for (PackageSetting ps : mSettings.mPackages.values()) {
8294 int effectiveFlags = flags;
8295 if (ps.isSystem()) {
8296 effectiveFlags |= PackageManager.MATCH_ANY_USER;
8298 if (ps.pkg != null) {
8299 if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8302 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
8305 ai = PackageInfoUtils.generateApplicationInfo(ps.pkg, effectiveFlags,
8306 ps.readUserState(userId), userId, ps);
8308 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
8311 // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
8312 // and already converts to externally visible package name
8313 ai = generateApplicationInfoFromSettingsLPw(ps.name,
8314 callingUid, effectiveFlags, userId);
8321 list = new ArrayList<>(mPackages.size());
8322 for (AndroidPackage p : mPackages.values()) {
8323 final PackageSetting ps = getPackageSetting(p.getPackageName());
8325 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
8328 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
8331 ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(p, flags,
8332 ps.readUserState(userId), userId, ps);
8334 ai.packageName = resolveExternalPackageNameLPr(p);
8346 public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
8347 if (HIDE_EPHEMERAL_APIS) {
8350 if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8351 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8352 "getEphemeralApplications");
8354 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8355 true /* requireFullPermission */, false /* checkShell */,
8356 "getEphemeralApplications");
8357 synchronized (mLock) {
8358 List<InstantAppInfo> instantApps = mInstantAppRegistry
8359 .getInstantAppsLPr(userId);
8360 if (instantApps != null) {
8361 return new ParceledListSlice<>(instantApps);
8368 public boolean isInstantApp(String packageName, int userId) {
8369 final int callingUid = Binder.getCallingUid();
8370 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
8371 true /* requireFullPermission */, false /* checkShell */,
8374 return isInstantAppInternal(packageName, userId, callingUid);
8377 private boolean isInstantAppInternal(String packageName, @UserIdInt int userId,
8379 if (HIDE_EPHEMERAL_APIS) {
8382 synchronized (mLock) {
8383 if (Process.isIsolated(callingUid)) {
8384 callingUid = mIsolatedOwners.get(callingUid);
8386 final PackageSetting ps = mSettings.mPackages.get(packageName);
8387 final boolean returnAllowed =
8389 && (isCallerSameApp(packageName, callingUid)
8390 || canViewInstantApps(callingUid, userId)
8391 || mInstantAppRegistry.isInstantAccessGranted(
8392 userId, UserHandle.getAppId(callingUid), ps.appId));
8393 if (returnAllowed) {
8394 return ps.getInstantApp(userId);
8401 public byte[] getInstantAppCookie(String packageName, int userId) {
8402 if (HIDE_EPHEMERAL_APIS) {
8406 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8407 true /* requireFullPermission */, false /* checkShell */,
8408 "getInstantAppCookie");
8409 if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8412 synchronized (mLock) {
8413 return mInstantAppRegistry.getInstantAppCookieLPw(
8414 packageName, userId);
8419 public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8420 if (HIDE_EPHEMERAL_APIS) {
8424 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8425 true /* requireFullPermission */, true /* checkShell */,
8426 "setInstantAppCookie");
8427 if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8430 synchronized (mLock) {
8431 return mInstantAppRegistry.setInstantAppCookieLPw(
8432 packageName, cookie, userId);
8437 public Bitmap getInstantAppIcon(String packageName, int userId) {
8438 if (HIDE_EPHEMERAL_APIS) {
8442 if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8443 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8444 "getInstantAppIcon");
8446 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8447 true /* requireFullPermission */, false /* checkShell */,
8448 "getInstantAppIcon");
8450 synchronized (mLock) {
8451 return mInstantAppRegistry.getInstantAppIconLPw(
8452 packageName, userId);
8456 private boolean isCallerSameApp(String packageName, int uid) {
8457 AndroidPackage pkg = mPackages.get(packageName);
8459 && UserHandle.getAppId(uid) == pkg.getUid();
8463 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8464 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8465 return ParceledListSlice.emptyList();
8467 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8470 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8471 final ArrayList<ApplicationInfo> finalList = new ArrayList<>();
8474 synchronized (mLock) {
8475 final Iterator<AndroidPackage> i = mPackages.values().iterator();
8476 final int userId = UserHandle.getCallingUserId();
8477 while (i.hasNext()) {
8478 final AndroidPackage p = i.next();
8480 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8481 && !p.isDirectBootAware();
8482 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8483 && p.isDirectBootAware();
8485 if (p.isPersistent()
8486 && (!mSafeMode || p.isSystem())
8487 && (matchesUnaware || matchesAware)) {
8488 PackageSetting ps = mSettings.mPackages.get(p.getPackageName());
8490 ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(p, flags,
8491 ps.readUserState(userId), userId, ps);
8504 public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8505 return resolveContentProviderInternal(name, flags, userId);
8508 private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
8509 if (!mUserManager.exists(userId)) return null;
8510 flags = updateFlagsForComponent(flags, userId);
8511 final int callingUid = Binder.getCallingUid();
8512 final ProviderInfo providerInfo = mComponentResolver.queryProvider(name, flags, userId);
8513 if (providerInfo == null) {
8516 if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
8519 synchronized (mLock) {
8520 final PackageSetting ps = mSettings.mPackages.get(providerInfo.packageName);
8521 final ComponentName component =
8522 new ComponentName(providerInfo.packageName, providerInfo.name);
8523 if (shouldFilterApplicationLocked(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8526 return providerInfo;
8534 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8535 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8538 mComponentResolver.querySyncProviders(
8539 outNames, outInfo, mSafeMode, UserHandle.getCallingUserId());
8543 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8544 int uid, int flags, String metaDataKey) {
8545 final int callingUid = Binder.getCallingUid();
8546 final int userId = processName != null ? UserHandle.getUserId(uid)
8547 : UserHandle.getCallingUserId();
8548 if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
8549 flags = updateFlagsForComponent(flags, userId);
8550 ArrayList<ProviderInfo> finalList = null;
8551 final List<ProviderInfo> matchList =
8552 mComponentResolver.queryProviders(processName, metaDataKey, uid, flags, userId);
8553 final int listSize = (matchList == null ? 0 : matchList.size());
8554 synchronized (mLock) {
8555 for (int i = 0; i < listSize; i++) {
8556 final ProviderInfo providerInfo = matchList.get(i);
8557 if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
8560 final PackageSetting ps = mSettings.mPackages.get(providerInfo.packageName);
8561 final ComponentName component =
8562 new ComponentName(providerInfo.packageName, providerInfo.name);
8563 if (shouldFilterApplicationLocked(
8564 ps, callingUid, component, TYPE_PROVIDER, userId)) {
8567 if (finalList == null) {
8568 finalList = new ArrayList<>(listSize - i);
8570 finalList.add(providerInfo);
8574 if (finalList != null) {
8575 finalList.sort(sProviderInitOrderSorter);
8576 return new ParceledListSlice<>(finalList);
8579 return ParceledListSlice.emptyList();
8583 public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8585 synchronized (mLock) {
8586 final int callingUid = Binder.getCallingUid();
8587 final int callingUserId = UserHandle.getUserId(callingUid);
8588 String packageName = component.getPackageName();
8589 final PackageSetting ps = mSettings.mPackages.get(packageName);
8590 AndroidPackage pkg = mPackages.get(packageName);
8591 if (ps == null || pkg == null) return null;
8592 if (shouldFilterApplicationLocked(
8593 ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8596 final ParsedInstrumentation i = mInstrumentation.get(component);
8597 return PackageInfoUtils.generateInstrumentationInfo(i, pkg, flags, callingUserId, ps);
8602 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8603 String targetPackage, int flags) {
8604 final int callingUid = Binder.getCallingUid();
8605 final int callingUserId = UserHandle.getUserId(callingUid);
8606 final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8607 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
8608 return ParceledListSlice.emptyList();
8610 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags,
8614 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8615 int flags, int userId) {
8616 ArrayList<InstrumentationInfo> finalList = new ArrayList<>();
8619 synchronized (mLock) {
8620 final Iterator<ParsedInstrumentation> i = mInstrumentation.values().iterator();
8621 while (i.hasNext()) {
8622 final ParsedInstrumentation p = i.next();
8623 if (targetPackage == null
8624 || targetPackage.equals(p.getTargetPackage())) {
8625 String packageName = p.getPackageName();
8626 AndroidPackage pkg = mPackages.get(packageName);
8627 PackageSetting pkgSetting = getPackageSetting(packageName);
8629 InstrumentationInfo ii = PackageInfoUtils.generateInstrumentationInfo(p,
8630 pkg, flags, userId, pkgSetting);
8642 private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags,
8643 long currentTime, PackageParser2 packageParser, ExecutorService executorService) {
8644 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
8646 scanDirLI(scanDir, parseFlags, scanFlags, currentTime, packageParser, executorService);
8648 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8652 private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime,
8653 PackageParser2 packageParser, ExecutorService executorService) {
8654 final File[] files = scanDir.listFiles();
8655 if (ArrayUtils.isEmpty(files)) {
8656 Log.d(TAG, "No files in app dir " + scanDir);
8660 if (DEBUG_PACKAGE_SCANNING) {
8661 Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
8662 + " flags=0x" + Integer.toHexString(parseFlags));
8665 ParallelPackageParser parallelPackageParser =
8666 new ParallelPackageParser(packageParser, executorService);
8668 // Submit files for parsing in parallel
8670 for (File file : files) {
8671 final boolean isPackage = (isApkFile(file) || file.isDirectory())
8672 && !PackageInstallerService.isStageName(file.getName());
8674 // Ignore entries which are not packages
8677 parallelPackageParser.submit(file, parseFlags);
8681 // Process results one by one
8682 for (; fileCount > 0; fileCount--) {
8683 ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8684 Throwable throwable = parseResult.throwable;
8685 int errorCode = PackageManager.INSTALL_SUCCEEDED;
8687 if (throwable == null) {
8688 // TODO(toddke): move lower in the scan chain
8689 // Static shared libraries have synthetic package names
8690 if (parseResult.parsedPackage.isStaticSharedLibrary()) {
8691 renameStaticSharedLibraryPackage(parseResult.parsedPackage);
8694 addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags,
8696 } catch (PackageManagerException e) {
8697 errorCode = e.error;
8698 Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8700 } else if (throwable instanceof PackageParserException) {
8701 PackageParserException e = (PackageParserException)
8703 errorCode = e.error;
8704 Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8706 throw new IllegalStateException("Unexpected exception occurred while parsing "
8707 + parseResult.scanFile, throwable);
8710 // Delete invalid userdata apps
8711 if ((scanFlags & SCAN_AS_SYSTEM) == 0
8712 && errorCode != PackageManager.INSTALL_SUCCEEDED) {
8713 logCriticalInfo(Log.WARN,
8714 "Deleting invalid package at " + parseResult.scanFile);
8715 removeCodePathLI(parseResult.scanFile);
8720 public static void reportSettingsProblem(int priority, String msg) {
8721 logCriticalInfo(priority, msg);
8724 private void collectCertificatesLI(PackageSetting ps, ParsedPackage parsedPackage,
8725 boolean forceCollect, boolean skipVerify) throws PackageManagerException {
8726 // When upgrading from pre-N MR1, verify the package time stamp using the package
8727 // directory and not the APK file.
8728 final long lastModifiedTime = mIsPreNMR1Upgrade
8729 ? new File(parsedPackage.getCodePath()).lastModified()
8730 : getLastModifiedTime(parsedPackage);
8731 final VersionInfo settingsVersionForPackage = getSettingsVersionForPackage(parsedPackage);
8732 if (ps != null && !forceCollect
8733 && ps.codePathString.equals(parsedPackage.getCodePath())
8734 && ps.timeStamp == lastModifiedTime
8735 && !isCompatSignatureUpdateNeeded(settingsVersionForPackage)
8736 && !isRecoverSignatureUpdateNeeded(settingsVersionForPackage)) {
8737 if (ps.signatures.mSigningDetails.signatures != null
8738 && ps.signatures.mSigningDetails.signatures.length != 0
8739 && ps.signatures.mSigningDetails.signatureSchemeVersion
8740 != SignatureSchemeVersion.UNKNOWN) {
8741 // Optimization: reuse the existing cached signing data
8742 // if the package appears to be unchanged.
8743 parsedPackage.setSigningDetails(
8744 new PackageParser.SigningDetails(ps.signatures.mSigningDetails));
8748 Slog.w(TAG, "PackageSetting for " + ps.name
8749 + " is missing signatures. Collecting certs again to recover them.");
8751 Slog.i(TAG, parsedPackage.getCodePath() + " changed; collecting certs" +
8752 (forceCollect ? " (forced)" : ""));
8756 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
8757 parsedPackage.setSigningDetails(
8758 ParsingPackageUtils.collectCertificates(parsedPackage, skipVerify));
8759 } catch (PackageParserException e) {
8760 throw PackageManagerException.from(e);
8762 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8767 * Clear the package profile if this was an upgrade and the package
8768 * version was updated.
8770 private void maybeClearProfilesForUpgradesLI(
8771 @Nullable PackageSetting originalPkgSetting,
8772 @NonNull AndroidPackage pkg) {
8773 if (originalPkgSetting == null || !isDeviceUpgrading()) {
8776 if (originalPkgSetting.versionCode == pkg.getVersionCode()) {
8780 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
8781 if (DEBUG_INSTALL) {
8782 Slog.d(TAG, originalPkgSetting.name
8783 + " clear profile due to version change "
8784 + originalPkgSetting.versionCode + " != "
8785 + pkg.getVersionCode());
8790 * Traces a package scan.
8791 * @see #scanPackageLI(File, int, int, long, UserHandle)
8793 @GuardedBy({"mInstallLock", "mLock"})
8794 private AndroidPackage scanPackageTracedLI(File scanFile, final int parseFlags,
8795 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8796 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
8798 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
8800 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8805 * Scans a package and returns the newly parsed package.
8806 * Returns {@code null} in case of errors and the error code is stored in mLastScanError
8808 @GuardedBy({"mInstallLock", "mLock"})
8809 private AndroidPackage scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8810 long currentTime, UserHandle user) throws PackageManagerException {
8811 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8812 PackageParser2 pp = new PackageParser2(mSeparateProcesses, mOnlyCore, mMetrics, null,
8813 mPackageParserCallback);
8815 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8816 final ParsedPackage parsedPackage;
8818 parsedPackage = pp.parsePackage(scanFile, parseFlags, false);
8819 } catch (PackageParserException e) {
8820 throw PackageManagerException.from(e);
8822 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8825 // Static shared libraries have synthetic package names
8826 if (parsedPackage.isStaticSharedLibrary()) {
8827 renameStaticSharedLibraryPackage(parsedPackage);
8830 return addForInitLI(parsedPackage, parseFlags, scanFlags, currentTime, user);
8834 * Returns if forced apk verification can be skipped for the whole package, including splits.
8836 private boolean canSkipForcedPackageVerification(AndroidPackage pkg) {
8837 if (!canSkipForcedApkVerification(pkg.getBaseCodePath())) {
8840 // TODO: Allow base and splits to be verified individually.
8841 String[] splitCodePaths = pkg.getSplitCodePaths();
8842 if (!ArrayUtils.isEmpty(splitCodePaths)) {
8843 for (int i = 0; i < splitCodePaths.length; i++) {
8844 if (!canSkipForcedApkVerification(splitCodePaths[i])) {
8853 * Returns if forced apk verification can be skipped, depending on current FSVerity setup and
8854 * whether the apk contains signed root hash. Note that the signer's certificate still needs to
8855 * match one in a trusted source, and should be done separately.
8857 private boolean canSkipForcedApkVerification(String apkPath) {
8858 if (!PackageManagerServiceUtils.isLegacyApkVerityEnabled()) {
8859 return VerityUtils.hasFsverity(apkPath);
8863 final byte[] rootHashObserved = VerityUtils.generateApkVerityRootHash(apkPath);
8864 if (rootHashObserved == null) {
8865 return false; // APK does not contain Merkle tree root hash.
8867 synchronized (mInstallLock) {
8868 // Returns whether the observed root hash matches what kernel has.
8869 mInstaller.assertFsverityRootHashMatches(apkPath, rootHashObserved);
8872 } catch (InstallerException | IOException | DigestException |
8873 NoSuchAlgorithmException e) {
8874 Slog.w(TAG, "Error in fsverity check. Fallback to full apk verification.", e);
8880 * Adds a new package to the internal data structures during platform initialization.
8881 * <p>After adding, the package is known to the system and available for querying.
8882 * <p>For packages located on the device ROM [eg. packages located in /system, /vendor,
8883 * etc...], additional checks are performed. Basic verification [such as ensuring
8884 * matching signatures, checking version codes, etc...] occurs if the package is
8885 * identical to a previously known package. If the package fails a signature check,
8886 * the version installed on /data will be removed. If the version of the new package
8887 * is less than or equal than the version on /data, it will be ignored.
8888 * <p>Regardless of the package location, the results are applied to the internal
8889 * structures and the package is made available to the rest of the system.
8890 * <p>NOTE: The return value should be removed. It's the passed in package object.
8892 @GuardedBy({"mInstallLock", "mLock"})
8893 private AndroidPackage addForInitLI(ParsedPackage parsedPackage,
8894 @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8895 @Nullable UserHandle user)
8896 throws PackageManagerException {
8897 final boolean scanSystemPartition = (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0;
8898 final String renamedPkgName;
8899 final PackageSetting disabledPkgSetting;
8900 final boolean isSystemPkgUpdated;
8901 final boolean pkgAlreadyExists;
8902 PackageSetting pkgSetting;
8904 synchronized (mLock) {
8905 renamedPkgName = mSettings.getRenamedPackageLPr(parsedPackage.getRealPackage());
8906 final String realPkgName = getRealPackageName(parsedPackage, renamedPkgName);
8907 if (realPkgName != null) {
8908 ensurePackageRenamed(parsedPackage, renamedPkgName);
8910 final PackageSetting originalPkgSetting = getOriginalPackageLocked(parsedPackage,
8912 final PackageSetting installedPkgSetting = mSettings.getPackageLPr(
8913 parsedPackage.getPackageName());
8914 pkgSetting = originalPkgSetting == null ? installedPkgSetting : originalPkgSetting;
8915 pkgAlreadyExists = pkgSetting != null;
8916 final String disabledPkgName = pkgAlreadyExists
8917 ? pkgSetting.name : parsedPackage.getPackageName();
8918 if (scanSystemPartition && !pkgAlreadyExists
8919 && mSettings.getDisabledSystemPkgLPr(disabledPkgName) != null) {
8920 // The updated-package data for /system apk remains inconsistently
8921 // after the package data for /data apk is lost accidentally.
8922 // To recover it, enable /system apk and install it as non-updated system app.
8923 Slog.w(TAG, "Inconsistent package setting of updated system app for "
8924 + disabledPkgName + ". To recover it, enable the system app"
8925 + "and install it as non-updated system app.");
8926 mSettings.removeDisabledSystemPackageLPw(disabledPkgName);
8928 disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(disabledPkgName);
8929 isSystemPkgUpdated = disabledPkgSetting != null;
8931 if (DEBUG_INSTALL && isSystemPkgUpdated) {
8932 Slog.d(TAG, "updatedPkg = " + disabledPkgSetting);
8935 final SharedUserSetting sharedUserSetting = (parsedPackage.getSharedUserId() != null)
8936 ? mSettings.getSharedUserLPw(parsedPackage.getSharedUserId(),
8937 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true)
8939 if (DEBUG_PACKAGE_SCANNING
8940 && (parseFlags & PackageParser.PARSE_CHATTY) != 0
8941 && sharedUserSetting != null) {
8942 Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId()
8943 + " (uid=" + sharedUserSetting.userId + "):"
8944 + " packages=" + sharedUserSetting.packages);
8947 if (scanSystemPartition) {
8948 if (isSystemPkgUpdated) {
8949 // we're updating the disabled package, so, scan it as the package setting
8950 boolean isPlatformPackage = mPlatformPackage != null
8951 && Objects.equals(mPlatformPackage.getPackageName(),
8952 parsedPackage.getPackageName());
8953 final ScanRequest request = new ScanRequest(parsedPackage, sharedUserSetting,
8954 null, disabledPkgSetting /* pkgSetting */,
8955 null /* disabledPkgSetting */, null /* originalPkgSetting */,
8956 null, parseFlags, scanFlags, isPlatformPackage, user, null);
8957 applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, true);
8958 final ScanResult scanResult =
8959 scanPackageOnlyLI(request, mInjector, mFactoryTest, -1L);
8960 if (scanResult.existingSettingCopied && scanResult.request.pkgSetting != null) {
8961 scanResult.request.pkgSetting.updateFrom(scanResult.pkgSetting);
8967 final boolean newPkgChangedPaths =
8968 pkgAlreadyExists && !pkgSetting.codePathString.equals(parsedPackage.getCodePath());
8969 final boolean newPkgVersionGreater =
8970 pkgAlreadyExists && parsedPackage.getLongVersionCode() > pkgSetting.versionCode;
8971 final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
8972 && newPkgChangedPaths && newPkgVersionGreater;
8973 if (isSystemPkgBetter) {
8974 // The version of the application on /system is greater than the version on
8975 // /data. Switch back to the application on /system.
8976 // It's safe to assume the application on /system will correctly scan. If not,
8977 // there won't be a working copy of the application.
8978 synchronized (mLock) {
8979 // just remove the loaded entries from package lists
8980 mPackages.remove(pkgSetting.name);
8983 logCriticalInfo(Log.WARN,
8984 "System package updated;"
8985 + " name: " + pkgSetting.name
8986 + "; " + pkgSetting.versionCode + " --> " + parsedPackage.getLongVersionCode()
8987 + "; " + pkgSetting.codePathString + " --> " + parsedPackage.getCodePath());
8989 final InstallArgs args = createInstallArgsForExisting(
8990 pkgSetting.codePathString,
8991 pkgSetting.resourcePathString, getAppDexInstructionSets(
8992 pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString));
8993 args.cleanUpResourcesLI();
8994 synchronized (mLock) {
8995 mSettings.enableSystemPackageLPw(pkgSetting.name);
8999 if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {
9000 // The version of the application on the /system partition is less than or
9001 // equal to the version on the /data partition. Throw an exception and use
9002 // the application already installed on the /data partition.
9003 throw new PackageManagerException(Log.WARN, "Package " + parsedPackage.getPackageName()
9004 + " at " + parsedPackage.getCodePath() + " ignored: updated version "
9005 + pkgSetting.versionCode + " better than this "
9006 + parsedPackage.getLongVersionCode());
9009 // Verify certificates against what was last scanned. Force re-collecting certificate in two
9011 // 1) when scanning system, force re-collect only if system is upgrading.
9012 // 2) when scannning /data, force re-collect only if the app is privileged (updated from
9013 // preinstall, or treated as privileged, e.g. due to shared user ID).
9014 final boolean forceCollect = scanSystemPartition ? mIsUpgrade
9015 : PackageManagerServiceUtils.isApkVerificationForced(pkgSetting);
9016 if (DEBUG_VERIFY && forceCollect) {
9017 Slog.d(TAG, "Force collect certificate of " + parsedPackage.getPackageName());
9020 // Full APK verification can be skipped during certificate collection, only if the file is
9021 // in verified partition, or can be verified on access (when apk verity is enabled). In both
9022 // cases, only data in Signing Block is verified instead of the whole file.
9023 // TODO(b/136132412): skip for Incremental installation
9024 final boolean skipVerify = scanSystemPartition
9025 || (forceCollect && canSkipForcedPackageVerification(parsedPackage));
9026 collectCertificatesLI(pkgSetting, parsedPackage, forceCollect, skipVerify);
9028 // Reset profile if the application version is changed
9029 maybeClearProfilesForUpgradesLI(pkgSetting, parsedPackage);
9032 * A new system app appeared, but we already had a non-system one of the
9033 * same name installed earlier.
9035 boolean shouldHideSystemApp = false;
9036 // A new application appeared on /system, but, we already have a copy of
9037 // the application installed on /data.
9038 if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists
9039 && !pkgSetting.isSystem()) {
9041 if (!parsedPackage.getSigningDetails()
9042 .checkCapability(pkgSetting.signatures.mSigningDetails,
9043 PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)
9044 && !pkgSetting.signatures.mSigningDetails.checkCapability(
9045 parsedPackage.getSigningDetails(),
9046 PackageParser.SigningDetails.CertCapabilities.ROLLBACK)) {
9047 logCriticalInfo(Log.WARN,
9048 "System package signature mismatch;"
9049 + " name: " + pkgSetting.name);
9050 try (@SuppressWarnings("unused") PackageFreezer freezer = freezePackage(
9051 parsedPackage.getPackageName(),
9052 "scanPackageInternalLI")) {
9053 deletePackageLIF(parsedPackage.getPackageName(), null, true, null, 0, null,
9057 } else if (newPkgVersionGreater) {
9058 // The application on /system is newer than the application on /data.
9059 // Simply remove the application on /data [keeping application data]
9060 // and replace it with the version on /system.
9061 logCriticalInfo(Log.WARN,
9062 "System package enabled;"
9063 + " name: " + pkgSetting.name
9064 + "; " + pkgSetting.versionCode + " --> "
9065 + parsedPackage.getLongVersionCode()
9066 + "; " + pkgSetting.codePathString + " --> "
9067 + parsedPackage.getCodePath());
9068 InstallArgs args = createInstallArgsForExisting(
9069 pkgSetting.codePathString,
9070 pkgSetting.resourcePathString, getAppDexInstructionSets(
9071 pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString));
9072 synchronized (mInstallLock) {
9073 args.cleanUpResourcesLI();
9076 // The application on /system is older than the application on /data. Hide
9077 // the application on /system and the version on /data will be scanned later
9078 // and re-added like an update.
9079 shouldHideSystemApp = true;
9080 logCriticalInfo(Log.INFO,
9081 "System package disabled;"
9082 + " name: " + pkgSetting.name
9083 + "; old: " + pkgSetting.codePathString + " @ "
9084 + pkgSetting.versionCode
9085 + "; new: " + parsedPackage.getCodePath() + " @ "
9086 + parsedPackage.getCodePath());
9090 final ScanResult scanResult = scanPackageNewLI(parsedPackage, parseFlags, scanFlags
9091 | SCAN_UPDATE_SIGNATURE, currentTime, user, null);
9092 if (scanResult.success) {
9093 synchronized (mLock) {
9094 boolean appIdCreated = false;
9096 final String pkgName = scanResult.pkgSetting.name;
9097 final Map<String, ReconciledPackage> reconcileResult = reconcilePackagesLocked(
9098 new ReconcileRequest(
9099 Collections.singletonMap(pkgName, scanResult),
9102 Collections.singletonMap(
9103 pkgName, getSettingsVersionForPackage(parsedPackage)),
9104 Collections.singletonMap(pkgName,
9105 getSharedLibLatestVersionSetting(scanResult))),
9106 mSettings.mKeySetManagerService);
9107 appIdCreated = optimisticallyRegisterAppId(scanResult);
9108 commitReconciledScanResultLocked(reconcileResult.get(pkgName));
9109 } catch (PackageManagerException e) {
9111 cleanUpAppIdCreation(scanResult);
9118 if (shouldHideSystemApp) {
9119 synchronized (mLock) {
9120 mSettings.disableSystemPackageLPw(parsedPackage.getPackageName(), true);
9123 return scanResult.pkgSetting.pkg;
9126 // TODO:(b/135203078): Move to parsing
9127 private static void renameStaticSharedLibraryPackage(ParsedPackage parsedPackage) {
9128 // Derive the new package synthetic package name
9129 parsedPackage.setPackageName(parsedPackage.getPackageName() + STATIC_SHARED_LIB_DELIMITER
9130 + parsedPackage.getStaticSharedLibVersion());
9133 static String fixProcessName(String defProcessName, String processName) {
9134 if (processName == null) {
9135 return defProcessName;
9141 * Enforces that only the system UID or root's UID can call a method exposed
9144 * @param message used as message if SecurityException is thrown
9145 * @throws SecurityException if the caller is not system or root
9147 private static void enforceSystemOrRoot(String message) {
9148 final int uid = Binder.getCallingUid();
9149 if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
9150 throw new SecurityException(message);
9155 * Enforces that only the system UID or root's UID or shell's UID can call
9156 * a method exposed via Binder.
9158 * @param message used as message if SecurityException is thrown
9159 * @throws SecurityException if the caller is not system or shell
9161 private static void enforceSystemOrRootOrShell(String message) {
9162 final int uid = Binder.getCallingUid();
9163 if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID && uid != Process.SHELL_UID) {
9164 throw new SecurityException(message);
9169 public void performFstrimIfNeeded() {
9170 enforceSystemOrRoot("Only the system can request fstrim");
9172 // Before everything else, see whether we need to fstrim.
9174 IStorageManager sm = PackageHelper.getStorageManager();
9176 boolean doTrim = false;
9177 final long interval = android.provider.Settings.Global.getLong(
9178 mContext.getContentResolver(),
9179 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
9180 DEFAULT_MANDATORY_FSTRIM_INTERVAL);
9182 final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
9183 if (timeSinceLast > interval) {
9185 Slog.w(TAG, "No disk maintenance in " + timeSinceLast
9186 + "; running immediately");
9190 final boolean dexOptDialogShown;
9191 synchronized (mLock) {
9192 dexOptDialogShown = mDexOptDialogShown;
9194 if (!isFirstBoot() && dexOptDialogShown) {
9196 ActivityManager.getService().showBootMessage(
9197 mContext.getResources().getString(
9198 R.string.android_upgrading_fstrim), true);
9199 } catch (RemoteException e) {
9202 sm.runMaintenance();
9205 Slog.e(TAG, "storageManager service unavailable!");
9207 } catch (RemoteException e) {
9208 // Can't happen; StorageManagerService is local
9213 public void updatePackagesIfNeeded() {
9214 enforceSystemOrRoot("Only the system can request package update");
9216 // We need to re-extract after an OTA.
9217 boolean causeUpgrade = isDeviceUpgrading();
9219 // First boot or factory reset.
9220 // Note: we also handle devices that are upgrading to N right now as if it is their
9221 // first boot, as they do not have profile data.
9222 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
9224 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
9225 boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
9227 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
9231 List<PackageSetting> pkgSettings;
9232 synchronized (mLock) {
9233 pkgSettings = PackageManagerServiceUtils.getPackagesForDexopt(
9234 mSettings.mPackages.values(), this);
9237 List<AndroidPackage> pkgs = new ArrayList<>(pkgSettings.size());
9238 for (int index = 0; index < pkgSettings.size(); index++) {
9239 pkgs.add(pkgSettings.get(index).pkg);
9242 final long startTime = System.nanoTime();
9243 final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
9244 causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
9245 false /* bootComplete */);
9247 final int elapsedTimeSeconds =
9248 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
9250 MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
9251 MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
9252 MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
9253 MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
9254 MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
9258 * Return the prebuilt profile path given a package base code path.
9260 private static String getPrebuildProfilePath(AndroidPackage pkg) {
9261 return pkg.getBaseCodePath() + ".prof";
9265 * Performs dexopt on the set of packages in {@code packages} and returns an int array
9266 * containing statistics about the invocation. The array consists of three elements,
9267 * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
9268 * and {@code numberOfPackagesFailed}.
9270 private int[] performDexOptUpgrade(List<AndroidPackage> pkgs, boolean showDialog,
9271 final int compilationReason, boolean bootComplete) {
9273 int numberOfPackagesVisited = 0;
9274 int numberOfPackagesOptimized = 0;
9275 int numberOfPackagesSkipped = 0;
9276 int numberOfPackagesFailed = 0;
9277 final int numberOfPackagesToDexopt = pkgs.size();
9279 for (AndroidPackage pkg : pkgs) {
9280 numberOfPackagesVisited++;
9282 boolean useProfileForDexopt = false;
9284 if ((isFirstBoot() || isDeviceUpgrading()) && pkg.isSystem()) {
9285 // Copy over initial preopt profiles since we won't get any JIT samples for methods
9286 // that are already compiled.
9287 File profileFile = new File(getPrebuildProfilePath(pkg));
9288 // Copy profile if it exists.
9289 if (profileFile.exists()) {
9291 // We could also do this lazily before calling dexopt in
9292 // PackageDexOptimizer to prevent this happening on first boot. The issue
9293 // is that we don't have a good way to say "do this only once".
9294 if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9295 pkg.getUid(), pkg.getPackageName(),
9296 ArtManager.getProfileName(null))) {
9297 Log.e(TAG, "Installer failed to copy system profile!");
9299 // Disabled as this causes speed-profile compilation during first boot
9300 // even if things are already compiled.
9301 // useProfileForDexopt = true;
9303 } catch (Exception e) {
9304 Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
9308 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(
9309 pkg.getPackageName());
9310 // Handle compressed APKs in this path. Only do this for stubs with profiles to
9311 // minimize the number off apps being speed-profile compiled during first boot.
9312 // The other paths will not change the filter.
9313 if (disabledPs != null && disabledPs.pkg.isStub()) {
9314 // The package is the stub one, remove the stub suffix to get the normal
9315 // package and APK names.
9316 String systemProfilePath =
9317 getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
9318 profileFile = new File(systemProfilePath);
9319 // If we have a profile for a compressed APK, copy it to the reference
9321 // Note that copying the profile here will cause it to override the
9322 // reference profile every OTA even though the existing reference profile
9323 // may have more data. We can't copy during decompression since the
9324 // directories are not set up at that point.
9325 if (profileFile.exists()) {
9327 // We could also do this lazily before calling dexopt in
9328 // PackageDexOptimizer to prevent this happening on first boot. The
9329 // issue is that we don't have a good way to say "do this only
9331 if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9332 pkg.getUid(), pkg.getPackageName(),
9333 ArtManager.getProfileName(null))) {
9334 Log.e(TAG, "Failed to copy system profile for stub package!");
9336 useProfileForDexopt = true;
9338 } catch (Exception e) {
9339 Log.e(TAG, "Failed to copy profile " +
9340 profileFile.getAbsolutePath() + " ", e);
9347 if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
9349 Log.i(TAG, "Skipping update of non-optimizable app " + pkg.getPackageName());
9351 numberOfPackagesSkipped++;
9356 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
9357 numberOfPackagesToDexopt + ": " + pkg.getPackageName());
9362 ActivityManager.getService().showBootMessage(
9363 mContext.getResources().getString(R.string.android_upgrading_apk,
9364 numberOfPackagesVisited, numberOfPackagesToDexopt), true);
9365 } catch (RemoteException e) {
9367 synchronized (mLock) {
9368 mDexOptDialogShown = true;
9372 int pkgCompilationReason = compilationReason;
9373 if (useProfileForDexopt) {
9374 // Use background dexopt mode to try and use the profile. Note that this does not
9375 // guarantee usage of the profile.
9376 pkgCompilationReason = PackageManagerService.REASON_BACKGROUND_DEXOPT;
9379 if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
9380 mArtManagerService.compileLayouts(pkg);
9383 // checkProfiles is false to avoid merging profiles during boot which
9384 // might interfere with background compilation (b/28612421).
9385 // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
9386 // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
9387 // trade-off worth doing to save boot time work.
9388 int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
9389 if (compilationReason == REASON_FIRST_BOOT) {
9390 // TODO: This doesn't cover the upgrade case, we should check for this too.
9391 dexoptFlags |= DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE;
9393 int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
9394 pkg.getPackageName(),
9395 pkgCompilationReason,
9398 switch (primaryDexOptStaus) {
9399 case PackageDexOptimizer.DEX_OPT_PERFORMED:
9400 numberOfPackagesOptimized++;
9402 case PackageDexOptimizer.DEX_OPT_SKIPPED:
9403 numberOfPackagesSkipped++;
9405 case PackageDexOptimizer.DEX_OPT_FAILED:
9406 numberOfPackagesFailed++;
9409 Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
9414 return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9415 numberOfPackagesFailed };
9419 public void notifyPackageUse(String packageName, int reason) {
9420 synchronized (mLock) {
9421 final int callingUid = Binder.getCallingUid();
9422 final int callingUserId = UserHandle.getUserId(callingUid);
9423 if (getInstantAppPackageName(callingUid) != null) {
9424 if (!isCallerSameApp(packageName, callingUid)) {
9428 if (isInstantApp(packageName, callingUserId)) {
9432 notifyPackageUseLocked(packageName, reason);
9437 private void notifyPackageUseLocked(String packageName, int reason) {
9438 final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
9439 if (pkgSetting == null) {
9442 pkgSetting.getPkgState().setLastPackageUsageTimeInMills(reason, System.currentTimeMillis());
9446 public void notifyDexLoad(String loadingPackageName, Map<String, String> classLoaderContextMap,
9448 int userId = UserHandle.getCallingUserId();
9449 ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
9451 Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
9452 + loadingPackageName + ", user=" + userId);
9455 mDexManager.notifyDexLoad(ai, classLoaderContextMap, loaderIsa, userId);
9459 public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
9460 IDexModuleRegisterCallback callback) {
9461 int userId = UserHandle.getCallingUserId();
9462 ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
9463 DexManager.RegisterDexModuleResult result;
9465 Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
9466 " calling user. package=" + packageName + ", user=" + userId);
9467 result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
9469 result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
9472 if (callback != null) {
9473 mHandler.post(() -> {
9475 callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
9476 } catch (RemoteException e) {
9477 Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
9484 * Ask the package manager to perform a dex-opt with the given compiler filter.
9486 * Note: exposed only for the shell command to allow moving packages explicitly to a
9490 public boolean performDexOptMode(String packageName,
9491 boolean checkProfiles, String targetCompilerFilter, boolean force,
9492 boolean bootComplete, String splitName) {
9493 int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
9494 (force ? DexoptOptions.DEXOPT_FORCE : 0) |
9495 (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
9496 return performDexOpt(new DexoptOptions(packageName, REASON_UNKNOWN,
9497 targetCompilerFilter, splitName, flags));
9501 * Ask the package manager to perform a dex-opt with the given compiler filter on the
9502 * secondary dex files belonging to the given package.
9504 * Note: exposed only for the shell command to allow moving packages explicitly to a
9508 public boolean performDexOptSecondary(String packageName, String compilerFilter,
9510 int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
9511 DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
9512 DexoptOptions.DEXOPT_BOOT_COMPLETE |
9513 (force ? DexoptOptions.DEXOPT_FORCE : 0);
9514 return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
9518 * Ask the package manager to compile layouts in the given package.
9521 public boolean compileLayouts(String packageName) {
9523 synchronized (mLock) {
9524 pkg = mPackages.get(packageName);
9529 return mViewCompiler.compileLayouts(pkg);
9532 /*package*/ boolean performDexOpt(DexoptOptions options) {
9533 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9535 } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
9539 if (options.isDexoptOnlySecondaryDex()) {
9540 return mDexManager.dexoptSecondaryDex(options);
9542 int dexoptStatus = performDexOptWithStatus(options);
9543 return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9548 * Perform dexopt on the given package and return one of following result:
9549 * {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
9550 * {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
9551 * {@link PackageDexOptimizer#DEX_OPT_FAILED}
9553 /* package */ int performDexOptWithStatus(DexoptOptions options) {
9554 return performDexOptTraced(options);
9557 private int performDexOptTraced(DexoptOptions options) {
9558 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9560 return performDexOptInternal(options);
9562 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9566 // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9567 // if the package can now be considered up to date for the given filter.
9568 private int performDexOptInternal(DexoptOptions options) {
9570 PackageSetting pkgSetting;
9571 synchronized (mLock) {
9572 p = mPackages.get(options.getPackageName());
9573 pkgSetting = mSettings.getPackageLPr(options.getPackageName());
9574 if (p == null || pkgSetting == null) {
9575 // Package could not be found. Report failure.
9576 return PackageDexOptimizer.DEX_OPT_FAILED;
9578 mPackageUsage.maybeWriteAsync(mSettings.mPackages);
9579 mCompilerStats.maybeWriteAsync();
9581 long callingId = Binder.clearCallingIdentity();
9583 synchronized (mInstallLock) {
9584 return performDexOptInternalWithDependenciesLI(p, pkgSetting, options);
9587 Binder.restoreCallingIdentity(callingId);
9591 public ArraySet<String> getOptimizablePackages() {
9592 ArraySet<String> pkgs = new ArraySet<>();
9593 synchronized (mLock) {
9594 for (AndroidPackage p : mPackages.values()) {
9595 if (PackageDexOptimizer.canOptimizePackage(p)) {
9596 pkgs.add(p.getPackageName());
9603 private int performDexOptInternalWithDependenciesLI(AndroidPackage p,
9604 @NonNull PackageSetting pkgSetting, DexoptOptions options) {
9605 // Select the dex optimizer based on the force parameter.
9606 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9607 // allocate an object here.
9608 PackageDexOptimizer pdo = options.isForce()
9609 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9610 : mPackageDexOptimizer;
9612 // Dexopt all dependencies first. Note: we ignore the return value and march on
9614 // Note that we are going to call performDexOpt on those libraries as many times as
9615 // they are referenced in packages. When we do a batch of performDexOpt (for example
9616 // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9617 // and the first package that uses the library will dexopt it. The
9618 // others will see that the compiled code for the library is up to date.
9619 Collection<SharedLibraryInfo> deps = findSharedLibraries(pkgSetting);
9620 final String[] instructionSets = getAppDexInstructionSets(
9621 AndroidPackageUtils.getPrimaryCpuAbi(p, pkgSetting),
9622 AndroidPackageUtils.getSecondaryCpuAbi(p, pkgSetting));
9623 if (!deps.isEmpty()) {
9624 DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
9625 options.getCompilationReason(), options.getCompilerFilter(),
9626 options.getSplitName(),
9627 options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
9628 for (SharedLibraryInfo info : deps) {
9629 AndroidPackage depPackage = null;
9630 PackageSetting depPackageSetting = null;
9631 synchronized (mLock) {
9632 depPackage = mPackages.get(info.getPackageName());
9633 depPackageSetting = mSettings.getPackageLPr(info.getPackageName());
9635 if (depPackage != null && depPackageSetting != null) {
9636 // TODO: Analyze and investigate if we (should) profile libraries.
9637 pdo.performDexOpt(depPackage, depPackageSetting, instructionSets,
9638 getOrCreateCompilerPackageStats(depPackage),
9639 mDexManager.getPackageUseInfoOrDefault(depPackage.getPackageName()),
9642 // TODO(ngeoffray): Support dexopting system shared libraries.
9647 return pdo.performDexOpt(p, pkgSetting, instructionSets,
9648 getOrCreateCompilerPackageStats(p),
9649 mDexManager.getPackageUseInfoOrDefault(p.getPackageName()), options);
9653 * Reconcile the information we have about the secondary dex files belonging to
9654 * {@code packageName} and the actual dex files. For all dex files that were
9655 * deleted, update the internal records and delete the generated oat files.
9658 public void reconcileSecondaryDexFiles(String packageName) {
9659 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9661 } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9664 mDexManager.reconcileSecondaryDexFiles(packageName);
9667 // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9668 // a reference there.
9669 /*package*/ DexManager getDexManager() {
9674 * Execute the background dexopt job immediately.
9677 public boolean runBackgroundDexoptJob(@Nullable List<String> packageNames) {
9678 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9681 enforceSystemOrRootOrShell("runBackgroundDexoptJob");
9682 final long identity = Binder.clearCallingIdentity();
9684 return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
9686 Binder.restoreCallingIdentity(identity);
9690 private static List<SharedLibraryInfo> findSharedLibraries(PackageSetting pkgSetting) {
9691 if (!pkgSetting.getPkgState().getUsesLibraryInfos().isEmpty()) {
9692 ArrayList<SharedLibraryInfo> retValue = new ArrayList<>();
9693 Set<String> collectedNames = new HashSet<>();
9694 for (SharedLibraryInfo info : pkgSetting.getPkgState().getUsesLibraryInfos()) {
9695 findSharedLibrariesRecursive(info, retValue, collectedNames);
9699 return Collections.emptyList();
9703 private static void findSharedLibrariesRecursive(SharedLibraryInfo info,
9704 ArrayList<SharedLibraryInfo> collected, Set<String> collectedNames) {
9705 if (!collectedNames.contains(info.getName())) {
9706 collectedNames.add(info.getName());
9707 collected.add(info);
9709 if (info.getDependencies() != null) {
9710 for (SharedLibraryInfo dep : info.getDependencies()) {
9711 findSharedLibrariesRecursive(dep, collected, collectedNames);
9717 List<PackageSetting> findSharedNonSystemLibraries(PackageSetting pkgSetting) {
9718 List<SharedLibraryInfo> deps = findSharedLibraries(pkgSetting);
9719 if (!deps.isEmpty()) {
9720 List<PackageSetting> retValue = new ArrayList<>();
9721 synchronized (mLock) {
9722 for (SharedLibraryInfo info : deps) {
9723 PackageSetting depPackageSetting =
9724 mSettings.getPackageLPr(info.getPackageName());
9725 if (depPackageSetting != null && depPackageSetting.pkg != null) {
9726 retValue.add(depPackageSetting);
9732 return Collections.emptyList();
9737 private SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version) {
9738 return getSharedLibraryInfo(name, version, mSharedLibraries, null);
9742 private static SharedLibraryInfo getSharedLibraryInfo(String name, long version,
9743 Map<String, LongSparseArray<SharedLibraryInfo>> existingLibraries,
9744 @Nullable Map<String, LongSparseArray<SharedLibraryInfo>> newLibraries) {
9745 if (newLibraries != null) {
9746 final LongSparseArray<SharedLibraryInfo> versionedLib = newLibraries.get(name);
9747 SharedLibraryInfo info = null;
9748 if (versionedLib != null) {
9749 info = versionedLib.get(version);
9755 final LongSparseArray<SharedLibraryInfo> versionedLib = existingLibraries.get(name);
9756 if (versionedLib == null) {
9759 return versionedLib.get(version);
9762 private SharedLibraryInfo getLatestSharedLibraVersionLPr(AndroidPackage pkg) {
9763 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(
9764 pkg.getStaticSharedLibName());
9765 if (versionedLib == null) {
9768 long previousLibVersion = -1;
9769 final int versionCount = versionedLib.size();
9770 for (int i = 0; i < versionCount; i++) {
9771 final long libVersion = versionedLib.keyAt(i);
9772 if (libVersion < pkg.getStaticSharedLibVersion()) {
9773 previousLibVersion = Math.max(previousLibVersion, libVersion);
9776 if (previousLibVersion >= 0) {
9777 return versionedLib.get(previousLibVersion);
9784 private PackageSetting getSharedLibLatestVersionSetting(@NonNull ScanResult scanResult) {
9785 PackageSetting sharedLibPackage = null;
9786 synchronized (mLock) {
9787 final SharedLibraryInfo latestSharedLibraVersionLPr =
9788 getLatestSharedLibraVersionLPr(scanResult.request.parsedPackage);
9789 if (latestSharedLibraVersionLPr != null) {
9790 sharedLibPackage = mSettings.getPackageLPr(
9791 latestSharedLibraVersionLPr.getPackageName());
9794 return sharedLibPackage;
9797 public void shutdown() {
9798 mPackageUsage.writeNow(mSettings.mPackages);
9799 mCompilerStats.writeNow();
9800 mDexManager.writePackageDexUsageNow();
9801 PackageWatchdog.getInstance(mContext).writeNow();
9803 // This is the last chance to write out pending restriction settings
9804 synchronized (mLock) {
9805 if (mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
9806 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
9807 for (int userId : mDirtyUsers) {
9808 mSettings.writePackageRestrictionsLPr(userId);
9810 mDirtyUsers.clear();
9816 public void dumpProfiles(String packageName) {
9818 synchronized (mLock) {
9819 pkg = mPackages.get(packageName);
9821 throw new IllegalArgumentException("Unknown package: " + packageName);
9824 /* Only the shell, root, or the app user should be able to dump profiles. */
9825 int callingUid = Binder.getCallingUid();
9826 if (callingUid != Process.SHELL_UID &&
9827 callingUid != Process.ROOT_UID &&
9828 callingUid != pkg.getUid()) {
9829 throw new SecurityException("dumpProfiles");
9832 synchronized (mInstallLock) {
9833 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
9834 mArtManagerService.dumpProfiles(pkg);
9835 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9840 public void forceDexOpt(String packageName) {
9841 enforceSystemOrRoot("forceDexOpt");
9844 PackageSetting pkgSetting;
9845 synchronized (mLock) {
9846 pkg = mPackages.get(packageName);
9847 pkgSetting = mSettings.getPackageLPr(packageName);
9848 if (pkg == null || pkgSetting == null) {
9849 throw new IllegalArgumentException("Unknown package: " + packageName);
9853 synchronized (mInstallLock) {
9854 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9856 // Whoever is calling forceDexOpt wants a compiled package.
9857 // Don't use profiles since that may cause compilation to be skipped.
9858 final int res = performDexOptInternalWithDependenciesLI(pkg, pkgSetting,
9859 new DexoptOptions(packageName,
9860 getDefaultCompilerFilter(),
9861 DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
9863 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9864 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
9865 throw new IllegalStateException("Failed to dexopt: " + res);
9871 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, AndroidPackage newPkg) {
9872 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9873 Slog.w(TAG, "Unable to update from " + oldPkg.name
9874 + " to " + newPkg.getPackageName()
9875 + ": old package not in system partition");
9877 } else if (mPackages.get(oldPkg.name) != null) {
9878 Slog.w(TAG, "Unable to update from " + oldPkg.name
9879 + " to " + newPkg.getPackageName()
9880 + ": old package still exists");
9886 @GuardedBy("mInstallLock")
9887 void removeCodePathLI(File codePath) {
9888 if (codePath.isDirectory()) {
9889 File codePathParent = codePath.getParentFile();
9891 mInstaller.rmPackageDir(codePath.getAbsolutePath());
9892 if (codePathParent.getName().startsWith(RANDOM_DIR_PREFIX)) {
9893 mInstaller.rmPackageDir(codePathParent.getAbsolutePath());
9895 } catch (InstallerException e) {
9896 Slog.w(TAG, "Failed to remove code path", e);
9903 private int[] resolveUserIds(int userId) {
9904 return (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds() : new int[] { userId };
9907 private void clearAppDataLIF(AndroidPackage pkg, int userId, int flags) {
9909 Slog.wtf(TAG, "Package was null!", new Throwable());
9912 clearAppDataLeafLIF(pkg, userId, flags);
9914 if ((flags & Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES) == 0) {
9915 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
9919 private void clearAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
9920 final PackageSetting ps;
9921 synchronized (mLock) {
9922 ps = mSettings.mPackages.get(pkg.getPackageName());
9924 for (int realUserId : resolveUserIds(userId)) {
9925 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9927 mInstaller.clearAppData(pkg.getVolumeUuid(), pkg.getPackageName(), realUserId,
9928 flags, ceDataInode);
9929 } catch (InstallerException e) {
9930 Slog.w(TAG, String.valueOf(e));
9935 private void destroyAppDataLIF(AndroidPackage pkg, int userId, int flags) {
9937 Slog.wtf(TAG, "Package was null!", new Throwable());
9940 destroyAppDataLeafLIF(pkg, userId, flags);
9943 private void destroyAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
9944 final PackageSetting ps;
9945 synchronized (mLock) {
9946 ps = mSettings.mPackages.get(pkg.getPackageName());
9948 for (int realUserId : resolveUserIds(userId)) {
9949 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9951 mInstaller.destroyAppData(pkg.getVolumeUuid(), pkg.getPackageName(), realUserId,
9952 flags, ceDataInode);
9953 } catch (InstallerException e) {
9954 Slog.w(TAG, String.valueOf(e));
9956 mDexManager.notifyPackageDataDestroyed(pkg.getPackageName(), userId);
9960 private void destroyAppProfilesLIF(AndroidPackage pkg) {
9962 Slog.wtf(TAG, "Package was null!", new Throwable());
9965 destroyAppProfilesLeafLIF(pkg);
9968 private void destroyAppProfilesLeafLIF(AndroidPackage pkg) {
9970 mInstaller.destroyAppProfiles(pkg.getPackageName());
9971 } catch (InstallerException e) {
9972 Slog.w(TAG, String.valueOf(e));
9976 private void clearAppProfilesLIF(AndroidPackage pkg, int userId) {
9978 Slog.wtf(TAG, "Package was null!", new Throwable());
9981 mArtManagerService.clearAppProfiles(pkg);
9985 private void applyDefiningSharedLibraryUpdateLocked(
9986 AndroidPackage pkg, SharedLibraryInfo libInfo,
9987 BiConsumer<SharedLibraryInfo, SharedLibraryInfo> action) {
9988 // Note that libraries defined by this package may be null if:
9989 // - Package manager was unable to create the shared library. The package still
9990 // gets installed, but the shared library does not get created.
9992 // - Package manager is in a state where package isn't scanned yet. This will
9993 // get called again after scanning to fix the dependencies.
9994 if (AndroidPackageUtils.isLibrary(pkg)) {
9995 if (pkg.getStaticSharedLibName() != null) {
9996 SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr(
9997 pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion());
9998 if (definedLibrary != null) {
9999 action.accept(definedLibrary, libInfo);
10002 for (String libraryName : pkg.getLibraryNames()) {
10003 SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr(
10004 libraryName, SharedLibraryInfo.VERSION_UNDEFINED);
10005 if (definedLibrary != null) {
10006 action.accept(definedLibrary, libInfo);
10013 @GuardedBy("mLock")
10014 private void addSharedLibraryLPr(AndroidPackage pkg, Set<String> usesLibraryFiles,
10015 SharedLibraryInfo libInfo, @Nullable AndroidPackage changingLib,
10016 @Nullable PackageSetting changingLibSetting) {
10017 if (libInfo.getPath() != null) {
10018 usesLibraryFiles.add(libInfo.getPath());
10021 AndroidPackage pkgForCodePaths = mPackages.get(libInfo.getPackageName());
10022 PackageSetting pkgSetting = mSettings.getPackageLPr(libInfo.getPackageName());
10023 if (changingLib != null && changingLib.getPackageName().equals(libInfo.getPackageName())) {
10024 // If we are doing this while in the middle of updating a library apk,
10025 // then we need to make sure to use that new apk for determining the
10026 // dependencies here. (We haven't yet finished committing the new apk
10027 // to the package manager state.)
10028 if (pkgForCodePaths == null
10029 || pkgForCodePaths.getPackageName().equals(changingLib.getPackageName())) {
10030 pkgForCodePaths = changingLib;
10031 pkgSetting = changingLibSetting;
10034 if (pkgForCodePaths != null) {
10035 usesLibraryFiles.addAll(AndroidPackageUtils.getAllCodePaths(pkgForCodePaths));
10036 // If the package provides libraries, add the dependency to them.
10037 applyDefiningSharedLibraryUpdateLocked(pkg, libInfo, SharedLibraryInfo::addDependency);
10038 if (pkgSetting != null) {
10039 usesLibraryFiles.addAll(pkgSetting.getPkgState().getUsesLibraryFiles());
10044 @GuardedBy("mLock")
10045 private void updateSharedLibrariesLocked(AndroidPackage pkg, PackageSetting pkgSetting,
10046 @Nullable AndroidPackage changingLib, @Nullable PackageSetting changingLibSetting,
10047 Map<String, AndroidPackage> availablePackages)
10048 throws PackageManagerException {
10049 final ArrayList<SharedLibraryInfo> sharedLibraryInfos = collectSharedLibraryInfos(
10050 pkgSetting.pkg, availablePackages, mSharedLibraries, null);
10051 executeSharedLibrariesUpdateLPr(pkg, pkgSetting, changingLib, changingLibSetting,
10052 sharedLibraryInfos);
10055 private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(AndroidPackage pkg,
10056 Map<String, AndroidPackage> availablePackages,
10057 @NonNull final Map<String, LongSparseArray<SharedLibraryInfo>> existingLibraries,
10058 @Nullable final Map<String, LongSparseArray<SharedLibraryInfo>> newLibraries)
10059 throws PackageManagerException {
10063 // The collection used here must maintain the order of addition (so
10064 // that libraries are searched in the correct order) and must have no
10066 ArrayList<SharedLibraryInfo> usesLibraryInfos = null;
10067 if (!pkg.getUsesLibraries().isEmpty()) {
10068 usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesLibraries(), null, null,
10069 pkg.getPackageName(), true, pkg.getTargetSdkVersion(), null,
10070 availablePackages, existingLibraries, newLibraries);
10072 if (!pkg.getUsesStaticLibraries().isEmpty()) {
10073 usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesStaticLibraries(),
10074 pkg.getUsesStaticLibrariesVersions(), pkg.getUsesStaticLibrariesCertDigests(),
10075 pkg.getPackageName(), true, pkg.getTargetSdkVersion(), usesLibraryInfos,
10076 availablePackages, existingLibraries, newLibraries);
10078 if (!pkg.getUsesOptionalLibraries().isEmpty()) {
10079 usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesOptionalLibraries(),
10080 null, null, pkg.getPackageName(), false, pkg.getTargetSdkVersion(),
10081 usesLibraryInfos, availablePackages, existingLibraries, newLibraries);
10083 return usesLibraryInfos;
10086 private void executeSharedLibrariesUpdateLPr(AndroidPackage pkg,
10087 @NonNull PackageSetting pkgSetting, @Nullable AndroidPackage changingLib,
10088 @Nullable PackageSetting changingLibSetting,
10089 ArrayList<SharedLibraryInfo> usesLibraryInfos) {
10090 // If the package provides libraries, clear their old dependencies.
10091 // This method will set them up again.
10092 applyDefiningSharedLibraryUpdateLocked(pkg, null, (definingLibrary, dependency) -> {
10093 definingLibrary.clearDependencies();
10095 if (usesLibraryInfos != null) {
10096 pkgSetting.getPkgState().setUsesLibraryInfos(usesLibraryInfos);
10097 // Use LinkedHashSet to preserve the order of files added to
10098 // usesLibraryFiles while eliminating duplicates.
10099 Set<String> usesLibraryFiles = new LinkedHashSet<>();
10100 for (SharedLibraryInfo libInfo : usesLibraryInfos) {
10101 addSharedLibraryLPr(pkg, usesLibraryFiles, libInfo, changingLib,
10102 changingLibSetting);
10104 pkgSetting.getPkgState().setUsesLibraryFiles(new ArrayList<>(usesLibraryFiles));
10106 pkgSetting.getPkgState().setUsesLibraryInfos(Collections.emptyList())
10107 .setUsesLibraryFiles(Collections.emptyList());
10111 @GuardedBy("mLock")
10112 private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(
10113 @NonNull List<String> requestedLibraries,
10114 @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
10115 @NonNull String packageName, boolean required, int targetSdk,
10116 @Nullable ArrayList<SharedLibraryInfo> outUsedLibraries,
10117 @NonNull final Map<String, AndroidPackage> availablePackages,
10118 @NonNull final Map<String, LongSparseArray<SharedLibraryInfo>> existingLibraries,
10119 @Nullable final Map<String, LongSparseArray<SharedLibraryInfo>> newLibraries)
10120 throws PackageManagerException {
10121 final int libCount = requestedLibraries.size();
10122 for (int i = 0; i < libCount; i++) {
10123 final String libName = requestedLibraries.get(i);
10124 final long libVersion = requiredVersions != null ? requiredVersions[i]
10125 : SharedLibraryInfo.VERSION_UNDEFINED;
10126 final SharedLibraryInfo libraryInfo = getSharedLibraryInfo(libName, libVersion,
10127 existingLibraries, newLibraries);
10128 if (libraryInfo == null) {
10130 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10131 "Package " + packageName + " requires unavailable shared library "
10132 + libName + "; failing!");
10133 } else if (DEBUG_SHARED_LIBRARIES) {
10134 Slog.i(TAG, "Package " + packageName
10135 + " desires unavailable shared library "
10136 + libName + "; ignoring!");
10139 if (requiredVersions != null && requiredCertDigests != null) {
10140 if (libraryInfo.getLongVersion() != requiredVersions[i]) {
10141 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10142 "Package " + packageName + " requires unavailable static shared"
10143 + " library " + libName + " version "
10144 + libraryInfo.getLongVersion() + "; failing!");
10146 AndroidPackage pkg = availablePackages.get(libraryInfo.getPackageName());
10147 SigningDetails libPkg = pkg == null ? null : pkg.getSigningDetails();
10148 if (libPkg == null) {
10149 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10150 "Package " + packageName + " requires unavailable static shared"
10151 + " library; failing!");
10153 final String[] expectedCertDigests = requiredCertDigests[i];
10154 if (expectedCertDigests.length > 1) {
10155 // For apps targeting O MR1 we require explicit enumeration of all certs.
10156 final String[] libCertDigests = (targetSdk >= Build.VERSION_CODES.O_MR1)
10157 ? PackageUtils.computeSignaturesSha256Digests(
10159 : PackageUtils.computeSignaturesSha256Digests(
10160 new Signature[]{libPkg.signatures[0]});
10162 // Take a shortcut if sizes don't match. Note that if an app doesn't
10163 // target O we don't parse the "additional-certificate" tags similarly
10164 // how we only consider all certs only for apps targeting O (see above).
10165 // Therefore, the size check is safe to make.
10166 if (expectedCertDigests.length != libCertDigests.length) {
10167 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10168 "Package " + packageName + " requires differently signed" +
10169 " static shared library; failing!");
10172 // Use a predictable order as signature order may vary
10173 Arrays.sort(libCertDigests);
10174 Arrays.sort(expectedCertDigests);
10176 final int certCount = libCertDigests.length;
10177 for (int j = 0; j < certCount; j++) {
10178 if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
10179 throw new PackageManagerException(
10180 INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10181 "Package " + packageName + " requires differently signed" +
10182 " static shared library; failing!");
10186 // lib signing cert could have rotated beyond the one expected, check to see
10187 // if the new one has been blessed by the old
10188 byte[] digestBytes = HexEncoding.decode(
10189 expectedCertDigests[0], false /* allowSingleChar */);
10190 if (!libPkg.hasSha256Certificate(digestBytes)) {
10191 throw new PackageManagerException(
10192 INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10193 "Package " + packageName + " requires differently signed" +
10194 " static shared library; failing!");
10198 if (outUsedLibraries == null) {
10199 outUsedLibraries = new ArrayList<>();
10201 outUsedLibraries.add(libraryInfo);
10204 return outUsedLibraries;
10207 private static boolean hasString(List<String> list, List<String> which) {
10208 if (list == null || which == null) {
10211 for (int i=list.size()-1; i>=0; i--) {
10212 for (int j=which.size()-1; j>=0; j--) {
10213 if (which.get(j).equals(list.get(i))) {
10221 @GuardedBy("mLock")
10222 private ArrayList<AndroidPackage> updateAllSharedLibrariesLocked(
10223 @Nullable AndroidPackage updatedPkg, @Nullable PackageSetting updatedPkgSetting,
10224 Map<String, AndroidPackage> availablePackages) {
10225 ArrayList<AndroidPackage> resultList = null;
10226 // Set of all descendants of a library; used to eliminate cycles
10227 ArraySet<String> descendants = null;
10228 // The current list of packages that need updating
10229 List<Pair<AndroidPackage, PackageSetting>> needsUpdating = null;
10230 if (updatedPkg != null && updatedPkgSetting != null) {
10231 needsUpdating = new ArrayList<>(1);
10232 needsUpdating.add(Pair.create(updatedPkg, updatedPkgSetting));
10235 final Pair<AndroidPackage, PackageSetting> changingPkgPair =
10236 (needsUpdating == null) ? null : needsUpdating.remove(0);
10237 final AndroidPackage changingPkg = changingPkgPair != null
10238 ? changingPkgPair.first : null;
10239 final PackageSetting changingPkgSetting = changingPkgPair != null
10240 ? changingPkgPair.second : null;
10241 for (int i = mPackages.size() - 1; i >= 0; --i) {
10242 final AndroidPackage pkg = mPackages.valueAt(i);
10243 final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.getPackageName());
10244 if (changingPkg != null
10245 && !hasString(pkg.getUsesLibraries(), changingPkg.getLibraryNames())
10246 && !hasString(pkg.getUsesOptionalLibraries(), changingPkg.getLibraryNames())
10247 && !ArrayUtils.contains(pkg.getUsesStaticLibraries(),
10248 changingPkg.getStaticSharedLibName())) {
10251 if (resultList == null) {
10252 resultList = new ArrayList<>();
10254 resultList.add(pkg);
10255 // if we're updating a shared library, all of its descendants must be updated
10256 if (changingPkg != null) {
10257 if (descendants == null) {
10258 descendants = new ArraySet<>();
10260 if (!descendants.contains(pkg.getPackageName())) {
10261 descendants.add(pkg.getPackageName());
10262 needsUpdating.add(Pair.create(pkg, pkgSetting));
10266 updateSharedLibrariesLocked(pkg, pkgSetting, changingPkg,
10267 changingPkgSetting, availablePackages);
10268 } catch (PackageManagerException e) {
10269 // If a system app update or an app and a required lib missing we
10270 // delete the package and for updated system apps keep the data as
10271 // it is better for the user to reinstall than to be in an limbo
10272 // state. Also libs disappearing under an app should never happen
10274 if (!pkg.isSystem() || pkgSetting.getPkgState().isUpdatedSystemApp()) {
10275 final int flags = pkgSetting.getPkgState().isUpdatedSystemApp()
10276 ? PackageManager.DELETE_KEEP_DATA : 0;
10277 deletePackageLIF(pkg.getPackageName(), null, true,
10278 mUserManager.getUserIds(), flags, null,
10281 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
10284 } while (needsUpdating != null && needsUpdating.size() > 0);
10288 @GuardedBy({"mInstallLock", "mLock"})
10289 private ScanResult scanPackageTracedLI(ParsedPackage parsedPackage,
10290 final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
10291 @Nullable UserHandle user, String cpuAbiOverride) throws PackageManagerException {
10292 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
10294 return scanPackageNewLI(parsedPackage, parseFlags, scanFlags, currentTime, user,
10297 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10301 /** The result of a package scan. */
10303 static class ScanResult {
10304 /** The request that initiated the scan that produced this result. */
10305 public final ScanRequest request;
10306 /** Whether or not the package scan was successful */
10307 public final boolean success;
10309 * Whether or not the original PackageSetting needs to be updated with this result on
10312 public final boolean existingSettingCopied;
10314 * The final package settings. This may be the same object passed in
10315 * the {@link ScanRequest}, but, with modified values.
10317 @Nullable public final PackageSetting pkgSetting;
10318 /** ABI code paths that have changed in the package scan */
10319 @Nullable public final List<String> changedAbiCodePath;
10321 public final SharedLibraryInfo staticSharedLibraryInfo;
10323 public final List<SharedLibraryInfo> dynamicSharedLibraryInfos;
10326 ScanRequest request, boolean success,
10327 @Nullable PackageSetting pkgSetting,
10328 @Nullable List<String> changedAbiCodePath, boolean existingSettingCopied,
10329 SharedLibraryInfo staticSharedLibraryInfo,
10330 List<SharedLibraryInfo> dynamicSharedLibraryInfos) {
10331 this.request = request;
10332 this.success = success;
10333 this.pkgSetting = pkgSetting;
10334 this.changedAbiCodePath = changedAbiCodePath;
10335 this.existingSettingCopied = existingSettingCopied;
10336 this.staticSharedLibraryInfo = staticSharedLibraryInfo;
10337 this.dynamicSharedLibraryInfos = dynamicSharedLibraryInfos;
10341 /** A package to be scanned */
10343 static class ScanRequest {
10344 /** The parsed package */
10345 @NonNull public final ParsedPackage parsedPackage;
10346 /** The package this package replaces */
10347 @Nullable public final AndroidPackage oldPkg;
10348 /** Shared user settings, if the package has a shared user */
10349 @Nullable public final SharedUserSetting sharedUserSetting;
10351 * Package settings of the currently installed version.
10352 * <p><em>IMPORTANT:</em> The contents of this object may be modified
10355 @Nullable public final PackageSetting pkgSetting;
10356 /** A copy of the settings for the currently installed version */
10357 @Nullable public final PackageSetting oldPkgSetting;
10358 /** Package settings for the disabled version on the /system partition */
10359 @Nullable public final PackageSetting disabledPkgSetting;
10360 /** Package settings for the installed version under its original package name */
10361 @Nullable public final PackageSetting originalPkgSetting;
10362 /** The real package name of a renamed application */
10363 @Nullable public final String realPkgName;
10364 public final @ParseFlags int parseFlags;
10365 public final @ScanFlags int scanFlags;
10366 /** The user for which the package is being scanned */
10367 @Nullable public final UserHandle user;
10368 /** Whether or not the platform package is being scanned */
10369 public final boolean isPlatformPackage;
10370 /** Override value for package ABI if set during install */
10372 public final String cpuAbiOverride;
10373 public ScanRequest(
10374 @NonNull ParsedPackage parsedPackage,
10375 @Nullable SharedUserSetting sharedUserSetting,
10376 @Nullable AndroidPackage oldPkg,
10377 @Nullable PackageSetting pkgSetting,
10378 @Nullable PackageSetting disabledPkgSetting,
10379 @Nullable PackageSetting originalPkgSetting,
10380 @Nullable String realPkgName,
10381 @ParseFlags int parseFlags,
10382 @ScanFlags int scanFlags,
10383 boolean isPlatformPackage,
10384 @Nullable UserHandle user,
10385 @Nullable String cpuAbiOverride) {
10386 this.parsedPackage = parsedPackage;
10387 this.oldPkg = oldPkg;
10388 this.pkgSetting = pkgSetting;
10389 this.sharedUserSetting = sharedUserSetting;
10390 this.oldPkgSetting = pkgSetting == null ? null : new PackageSetting(pkgSetting);
10391 this.disabledPkgSetting = disabledPkgSetting;
10392 this.originalPkgSetting = originalPkgSetting;
10393 this.realPkgName = realPkgName;
10394 this.parseFlags = parseFlags;
10395 this.scanFlags = scanFlags;
10396 this.isPlatformPackage = isPlatformPackage;
10398 this.cpuAbiOverride = cpuAbiOverride;
10403 * Returns the actual scan flags depending upon the state of the other settings.
10404 * <p>Updated system applications will not have the following flags set
10405 * by default and need to be adjusted after the fact:
10407 * <li>{@link #SCAN_AS_SYSTEM}</li>
10408 * <li>{@link #SCAN_AS_PRIVILEGED}</li>
10409 * <li>{@link #SCAN_AS_OEM}</li>
10410 * <li>{@link #SCAN_AS_VENDOR}</li>
10411 * <li>{@link #SCAN_AS_PRODUCT}</li>
10412 * <li>{@link #SCAN_AS_SYSTEM_EXT}</li>
10413 * <li>{@link #SCAN_AS_INSTANT_APP}</li>
10414 * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
10415 * <li>{@link #SCAN_AS_ODM}</li>
10418 private @ScanFlags int adjustScanFlags(@ScanFlags int scanFlags,
10419 PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user,
10420 AndroidPackage pkg) {
10422 // TODO(patb): Do away entirely with disabledPkgSetting here. PkgSetting will always contain
10423 // the correct isSystem value now that we don't disable system packages before scan.
10424 final PackageSetting systemPkgSetting =
10425 (scanFlags & SCAN_NEW_INSTALL) != 0 && disabledPkgSetting == null
10426 && pkgSetting != null && pkgSetting.isSystem()
10428 : disabledPkgSetting;
10429 if (systemPkgSetting != null) {
10430 // updated system application, must at least have SCAN_AS_SYSTEM
10431 scanFlags |= SCAN_AS_SYSTEM;
10432 if ((systemPkgSetting.pkgPrivateFlags
10433 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
10434 scanFlags |= SCAN_AS_PRIVILEGED;
10436 if ((systemPkgSetting.pkgPrivateFlags
10437 & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
10438 scanFlags |= SCAN_AS_OEM;
10440 if ((systemPkgSetting.pkgPrivateFlags
10441 & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
10442 scanFlags |= SCAN_AS_VENDOR;
10444 if ((systemPkgSetting.pkgPrivateFlags
10445 & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0) {
10446 scanFlags |= SCAN_AS_PRODUCT;
10448 if ((systemPkgSetting.pkgPrivateFlags
10449 & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0) {
10450 scanFlags |= SCAN_AS_SYSTEM_EXT;
10452 if ((systemPkgSetting.pkgPrivateFlags
10453 & ApplicationInfo.PRIVATE_FLAG_ODM) != 0) {
10454 scanFlags |= SCAN_AS_ODM;
10457 if (pkgSetting != null) {
10458 final int userId = ((user == null) ? 0 : user.getIdentifier());
10459 if (pkgSetting.getInstantApp(userId)) {
10460 scanFlags |= SCAN_AS_INSTANT_APP;
10462 if (pkgSetting.getVirtulalPreload(userId)) {
10463 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
10467 // Scan as privileged apps that share a user with a priv-app.
10468 final boolean skipVendorPrivilegeScan = ((scanFlags & SCAN_AS_VENDOR) != 0)
10469 && SystemProperties.getInt("ro.vndk.version", 28) < 28;
10470 if (((scanFlags & SCAN_AS_PRIVILEGED) == 0)
10471 && !pkg.isPrivileged()
10472 && (pkg.getSharedUserId() != null)
10473 && !skipVendorPrivilegeScan) {
10474 SharedUserSetting sharedUserSetting = null;
10476 sharedUserSetting = mSettings.getSharedUserLPw(pkg.getSharedUserId(), 0,
10478 } catch (PackageManagerException ignore) {
10480 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
10481 // Exempt SharedUsers signed with the platform key.
10482 // TODO(b/72378145) Fix this exemption. Force signature apps
10483 // to whitelist their privileged permissions just like other
10485 synchronized (mLock) {
10486 PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
10487 if ((compareSignatures(platformPkgSetting.signatures.mSigningDetails.signatures,
10488 pkg.getSigningDetails().signatures)
10489 != PackageManager.SIGNATURE_MATCH)) {
10490 scanFlags |= SCAN_AS_PRIVILEGED;
10499 // TODO: scanPackageNewLI() and scanPackageOnly() should be merged. But, first, commiting
10500 // the results / removing app data needs to be moved up a level to the callers of this
10501 // method. Also, we need to solve the problem of potentially creating a new shared user
10502 // setting. That can probably be done later and patch things up after the fact.
10503 @GuardedBy({"mInstallLock", "mLock"})
10504 private ScanResult scanPackageNewLI(@NonNull ParsedPackage parsedPackage,
10505 final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
10506 @Nullable UserHandle user, String cpuAbiOverride) throws PackageManagerException {
10508 final String renamedPkgName = mSettings.getRenamedPackageLPr(
10509 parsedPackage.getRealPackage());
10510 final String realPkgName = getRealPackageName(parsedPackage, renamedPkgName);
10511 if (realPkgName != null) {
10512 ensurePackageRenamed(parsedPackage, renamedPkgName);
10514 final PackageSetting originalPkgSetting = getOriginalPackageLocked(parsedPackage,
10516 final PackageSetting pkgSetting = mSettings.getPackageLPr(parsedPackage.getPackageName());
10517 final PackageSetting disabledPkgSetting =
10518 mSettings.getDisabledSystemPkgLPr(parsedPackage.getPackageName());
10520 if (mTransferredPackages.contains(parsedPackage.getPackageName())) {
10521 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
10522 + " was transferred to another, but its .apk remains");
10525 scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, parsedPackage);
10526 synchronized (mLock) {
10527 boolean isUpdatedSystemApp;
10528 if (pkgSetting != null) {
10529 isUpdatedSystemApp = pkgSetting.getPkgState().isUpdatedSystemApp();
10531 isUpdatedSystemApp = disabledPkgSetting != null;
10533 applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, isUpdatedSystemApp);
10534 assertPackageIsValid(parsedPackage, parseFlags, scanFlags);
10536 SharedUserSetting sharedUserSetting = null;
10537 if (parsedPackage.getSharedUserId() != null) {
10538 // SIDE EFFECTS; may potentially allocate a new shared user
10539 sharedUserSetting = mSettings.getSharedUserLPw(parsedPackage.getSharedUserId(),
10540 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
10541 if (DEBUG_PACKAGE_SCANNING) {
10542 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
10543 Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId()
10544 + " (uid=" + sharedUserSetting.userId + "):"
10545 + " packages=" + sharedUserSetting.packages);
10548 String platformPackageName = mPlatformPackage == null
10549 ? null : mPlatformPackage.getPackageName();
10550 final ScanRequest request = new ScanRequest(parsedPackage, sharedUserSetting,
10551 pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting,
10552 originalPkgSetting, realPkgName, parseFlags, scanFlags,
10553 Objects.equals(parsedPackage.getPackageName(), platformPackageName), user,
10555 return scanPackageOnlyLI(request, mInjector, mFactoryTest, currentTime);
10561 * Prepares the system to commit a {@link ScanResult} in a way that will not fail by registering
10562 * the app ID required for reconcile.
10563 * @return {@code true} if a new app ID was registered and will need to be cleaned up on
10566 private boolean optimisticallyRegisterAppId(@NonNull ScanResult result)
10567 throws PackageManagerException {
10568 if (!result.existingSettingCopied) {
10569 // THROWS: when we can't allocate a user id. add call to check if there's
10570 // enough space to ensure we won't throw; otherwise, don't modify state
10571 return mSettings.registerAppIdLPw(result.pkgSetting);
10577 * Reverts any app ID creation that were made by
10578 * {@link #optimisticallyRegisterAppId(ScanResult)}. Note: this is only necessary if the
10579 * referenced method returned true.
10581 private void cleanUpAppIdCreation(@NonNull ScanResult result) {
10582 // iff we've acquired an app ID for a new package setting, remove it so that it can be
10583 // acquired by another request.
10584 if (result.pkgSetting.appId > 0) {
10585 mSettings.removeAppIdLPw(result.pkgSetting.appId);
10590 * Commits the package scan and modifies system state.
10591 * <p><em>WARNING:</em> The method may throw an excpetion in the middle
10592 * of committing the package, leaving the system in an inconsistent state.
10593 * This needs to be fixed so, once we get to this point, no errors are
10594 * possible and the system is not left in an inconsistent state.
10596 @GuardedBy({"mLock", "mInstallLock"})
10597 private AndroidPackage commitReconciledScanResultLocked(
10598 @NonNull ReconciledPackage reconciledPkg) {
10599 final ScanResult result = reconciledPkg.scanResult;
10600 final ScanRequest request = result.request;
10601 // TODO(b/135203078): Move this even further away
10602 ParsedPackage parsedPackage = request.parsedPackage;
10603 if ("android".equals(parsedPackage.getPackageName())) {
10604 // TODO(b/135203078): Move this to initial parse
10605 parsedPackage.setVersionCode(mSdkVersion)
10606 .setVersionCodeMajor(0);
10608 final AndroidPackage oldPkg = request.oldPkg;
10609 final @ParseFlags int parseFlags = request.parseFlags;
10610 final @ScanFlags int scanFlags = request.scanFlags;
10611 final PackageSetting oldPkgSetting = request.oldPkgSetting;
10612 final PackageSetting originalPkgSetting = request.originalPkgSetting;
10613 final UserHandle user = request.user;
10614 final String realPkgName = request.realPkgName;
10615 final List<String> changedAbiCodePath = result.changedAbiCodePath;
10616 final PackageSetting pkgSetting;
10617 if (request.pkgSetting != null && request.pkgSetting.sharedUser != null
10618 && request.pkgSetting.sharedUser != result.pkgSetting.sharedUser) {
10619 // shared user changed, remove from old shared user
10620 request.pkgSetting.sharedUser.removePackage(request.pkgSetting);
10622 if (result.existingSettingCopied) {
10623 pkgSetting = request.pkgSetting;
10624 pkgSetting.updateFrom(result.pkgSetting);
10626 pkgSetting = result.pkgSetting;
10627 if (originalPkgSetting != null) {
10628 mSettings.addRenamedPackageLPw(parsedPackage.getPackageName(),
10629 originalPkgSetting.name);
10630 mTransferredPackages.add(originalPkgSetting.name);
10633 if (pkgSetting.sharedUser != null) {
10634 pkgSetting.sharedUser.addPackage(pkgSetting);
10636 if (reconciledPkg.installArgs != null && reconciledPkg.installArgs.forceQueryableOverride) {
10637 pkgSetting.forceQueryableOverride = true;
10640 // TODO(toddke): Consider a method specifically for modifying the Package object
10641 // post scan; or, moving this stuff out of the Package object since it has nothing
10642 // to do with the package on disk.
10643 // We need to have this here because addUserToSettingLPw() is sometimes responsible
10644 // for creating the application ID. If we did this earlier, we would be saving the
10646 parsedPackage.setUid(pkgSetting.appId);
10647 final AndroidPackage pkg = parsedPackage.hideAsFinal();
10649 mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
10651 if (realPkgName != null) {
10652 mTransferredPackages.add(pkg.getPackageName());
10655 if (reconciledPkg.collectedSharedLibraryInfos != null) {
10656 executeSharedLibrariesUpdateLPr(pkg, pkgSetting, null, null,
10657 reconciledPkg.collectedSharedLibraryInfos);
10660 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
10661 if (reconciledPkg.removeAppKeySetData) {
10662 ksms.removeAppKeySetDataLPw(pkg.getPackageName());
10664 if (reconciledPkg.sharedUserSignaturesChanged) {
10665 pkgSetting.sharedUser.signaturesChanged = Boolean.TRUE;
10666 pkgSetting.sharedUser.signatures.mSigningDetails = reconciledPkg.signingDetails;
10668 pkgSetting.signatures.mSigningDetails = reconciledPkg.signingDetails;
10670 if (!pkg.getAdoptPermissions().isEmpty()) {
10671 // This package wants to adopt ownership of permissions from
10672 // another package.
10673 for (int i = pkg.getAdoptPermissions().size() - 1; i >= 0; i--) {
10674 final String origName = pkg.getAdoptPermissions().get(i);
10675 final PackageSetting orig = mSettings.getPackageLPr(origName);
10676 if (orig != null) {
10677 if (verifyPackageUpdateLPr(orig, pkg)) {
10678 Slog.i(TAG, "Adopting permissions from " + origName + " to "
10679 + pkg.getPackageName());
10680 mSettings.mPermissions.transferPermissions(origName, pkg.getPackageName());
10686 if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
10687 for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
10688 final String codePathString = changedAbiCodePath.get(i);
10690 mInstaller.rmdex(codePathString,
10691 getDexCodeInstructionSet(getPreferredInstructionSet()));
10692 } catch (InstallerException ignored) {
10697 final int userId = user == null ? 0 : user.getIdentifier();
10698 // Modify state for the given package setting
10699 commitPackageSettings(pkg, oldPkg, pkgSetting, scanFlags,
10700 (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/, reconciledPkg);
10701 if (pkgSetting.getInstantApp(userId)) {
10702 mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
10709 * Returns the "real" name of the package.
10710 * <p>This may differ from the package's actual name if the application has already
10711 * been installed under one of this package's original names.
10713 private static @Nullable String getRealPackageName(@NonNull AndroidPackage pkg,
10714 @Nullable String renamedPkgName) {
10715 if (isPackageRenamed(pkg, renamedPkgName)) {
10716 return pkg.getRealPackage();
10721 /** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */
10722 private static boolean isPackageRenamed(@NonNull AndroidPackage pkg,
10723 @Nullable String renamedPkgName) {
10724 return pkg.getOriginalPackages().contains(renamedPkgName);
10728 * Returns the original package setting.
10729 * <p>A package can migrate its name during an update. In this scenario, a package
10730 * designates a set of names that it considers as one of its original names.
10731 * <p>An original package must be signed identically and it must have the same
10732 * shared user [if any].
10734 @GuardedBy("mLock")
10735 private @Nullable PackageSetting getOriginalPackageLocked(@NonNull AndroidPackage pkg,
10736 @Nullable String renamedPkgName) {
10737 if (!isPackageRenamed(pkg, renamedPkgName)) {
10740 for (int i = ArrayUtils.size(pkg.getOriginalPackages()) - 1; i >= 0; --i) {
10741 final PackageSetting originalPs =
10742 mSettings.getPackageLPr(pkg.getOriginalPackages().get(i));
10743 if (originalPs != null) {
10744 // the package is already installed under its original name...
10745 // but, should we use it?
10746 if (!verifyPackageUpdateLPr(originalPs, pkg)) {
10747 // the new package is incompatible with the original
10749 } else if (originalPs.sharedUser != null) {
10750 if (!originalPs.sharedUser.name.equals(pkg.getSharedUserId())) {
10751 // the shared user id is incompatible with the original
10752 Slog.w(TAG, "Unable to migrate data from " + originalPs.name
10753 + " to " + pkg.getPackageName() + ": old uid "
10754 + originalPs.sharedUser.name
10755 + " differs from " + pkg.getSharedUserId());
10758 // TODO: Add case when shared user id is added [b/28144775]
10760 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10761 + pkg.getPackageName() + " to old name " + originalPs.name);
10770 * Renames the package if it was installed under a different name.
10771 * <p>When we've already installed the package under an original name, update
10772 * the new package so we can continue to have the old name.
10774 private static void ensurePackageRenamed(@NonNull ParsedPackage parsedPackage,
10775 @NonNull String renamedPackageName) {
10776 if (!parsedPackage.getOriginalPackages().contains(renamedPackageName)
10777 || parsedPackage.getPackageName().equals(renamedPackageName)) {
10780 parsedPackage.setPackageName(renamedPackageName);
10784 * Applies the adjusted ABI calculated by
10785 * {@link PackageAbiHelper#getAdjustedAbiForSharedUser(Set, AndroidPackage)} to all
10786 * relevant packages and settings.
10787 * @param sharedUserSetting The {@code SharedUserSetting} to adjust
10788 * @param scannedPackage the package being scanned or null
10789 * @param adjustedAbi the adjusted ABI calculated by {@link PackageAbiHelper}
10790 * @return the list of code paths that belong to packages that had their ABIs adjusted.
10792 private static List<String> applyAdjustedAbiToSharedUser(SharedUserSetting sharedUserSetting,
10793 ParsedPackage scannedPackage, String adjustedAbi) {
10794 if (scannedPackage != null) {
10795 scannedPackage.setPrimaryCpuAbi(adjustedAbi);
10797 List<String> changedAbiCodePath = null;
10798 for (PackageSetting ps : sharedUserSetting.packages) {
10799 if (scannedPackage == null || !scannedPackage.getPackageName().equals(ps.name)) {
10800 if (ps.primaryCpuAbiString != null) {
10804 ps.primaryCpuAbiString = adjustedAbi;
10805 if (ps.pkg != null) {
10806 if (!TextUtils.equals(adjustedAbi,
10807 AndroidPackageUtils.getRawPrimaryCpuAbi(ps.pkg))) {
10808 if (DEBUG_ABI_SELECTION) {
10810 "Adjusting ABI for " + ps.name + " to " + adjustedAbi
10811 + " (scannedPackage="
10812 + (scannedPackage != null ? scannedPackage : "null")
10815 if (changedAbiCodePath == null) {
10816 changedAbiCodePath = new ArrayList<>();
10818 changedAbiCodePath.add(ps.codePathString);
10823 return changedAbiCodePath;
10827 * Sets the enabled state of components configured through {@link SystemConfig}.
10828 * This modifies the {@link PackageSetting} object.
10830 * TODO(b/135203078): Move this to package parsing
10832 static void configurePackageComponents(AndroidPackage pkg) {
10833 final ArrayMap<String, Boolean> componentsEnabledStates = SystemConfig.getInstance()
10834 .getComponentsEnabledStates(pkg.getPackageName());
10835 if (componentsEnabledStates == null) {
10839 for (int i = ArrayUtils.size(pkg.getActivities()) - 1; i >= 0; i--) {
10840 final ParsedActivity component = pkg.getActivities().get(i);
10841 final Boolean enabled = componentsEnabledStates.get(component.getName());
10842 if (enabled != null) {
10843 component.setEnabled(enabled);
10847 for (int i = ArrayUtils.size(pkg.getReceivers()) - 1; i >= 0; i--) {
10848 final ParsedActivity component = pkg.getReceivers().get(i);
10849 final Boolean enabled = componentsEnabledStates.get(component.getName());
10850 if (enabled != null) {
10851 component.setEnabled(enabled);
10855 for (int i = ArrayUtils.size(pkg.getProviders()) - 1; i >= 0; i--) {
10856 final ParsedProvider component = pkg.getProviders().get(i);
10857 final Boolean enabled = componentsEnabledStates.get(component.getName());
10858 if (enabled != null) {
10859 component.setEnabled(enabled);
10863 for (int i = ArrayUtils.size(pkg.getServices()) - 1; i >= 0; i--) {
10864 final ParsedService component = pkg.getServices().get(i);
10865 final Boolean enabled = componentsEnabledStates.get(component.getName());
10866 if (enabled != null) {
10867 component.setEnabled(enabled);
10874 * Just scans the package without any side effects.
10875 * <p>Not entirely true at the moment. There is still one side effect -- this
10876 * method potentially modifies a live {@link PackageSetting} object representing
10877 * the package being scanned. This will be resolved in the future.
10879 * @param injector injector for acquiring dependencies
10880 * @param request Information about the package to be scanned
10881 * @param isUnderFactoryTest Whether or not the device is under factory test
10882 * @param currentTime The current time, in millis
10883 * @return The results of the scan
10885 @GuardedBy("mInstallLock")
10888 static ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
10890 boolean isUnderFactoryTest, long currentTime)
10891 throws PackageManagerException {
10892 final PackageAbiHelper packageAbiHelper = injector.getAbiHelper();
10893 final UserManagerInternal userManager = injector.getUserManagerInternal();
10894 ParsedPackage parsedPackage = request.parsedPackage;
10895 PackageSetting pkgSetting = request.pkgSetting;
10896 final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
10897 final PackageSetting originalPkgSetting = request.originalPkgSetting;
10898 final @ParseFlags int parseFlags = request.parseFlags;
10899 final @ScanFlags int scanFlags = request.scanFlags;
10900 final String realPkgName = request.realPkgName;
10901 final SharedUserSetting sharedUserSetting = request.sharedUserSetting;
10902 final UserHandle user = request.user;
10903 final boolean isPlatformPackage = request.isPlatformPackage;
10905 List<String> changedAbiCodePath = null;
10907 if (DEBUG_PACKAGE_SCANNING) {
10908 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
10909 Log.d(TAG, "Scanning package " + parsedPackage.getPackageName());
10912 // Initialize package source and resource directories
10913 final File destCodeFile = new File(parsedPackage.getCodePath());
10914 final File destResourceFile = new File(parsedPackage.getCodePath());
10916 // We keep references to the derived CPU Abis from settings in oder to reuse
10917 // them in the case where we're not upgrading or booting for the first time.
10918 String primaryCpuAbiFromSettings = null;
10919 String secondaryCpuAbiFromSettings = null;
10920 boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
10921 if (!needToDeriveAbi) {
10922 if (pkgSetting != null) {
10923 primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
10924 secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
10926 // Re-scanning a system package after uninstalling updates; need to derive ABI
10927 needToDeriveAbi = true;
10931 if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) {
10932 PackageManagerService.reportSettingsProblem(Log.WARN,
10933 "Package " + parsedPackage.getPackageName() + " shared user changed from "
10934 + (pkgSetting.sharedUser != null
10935 ? pkgSetting.sharedUser.name : "<nothing>")
10937 + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
10938 + "; replacing with new");
10942 String[] usesStaticLibraries = null;
10943 if (!parsedPackage.getUsesStaticLibraries().isEmpty()) {
10944 usesStaticLibraries = new String[parsedPackage.getUsesStaticLibraries().size()];
10945 parsedPackage.getUsesStaticLibraries().toArray(usesStaticLibraries);
10947 // TODO(b/135203078): Remove appInfoFlag usage in favor of individually assigned booleans
10948 // to avoid adding something that's unsupported due to lack of state, since it's called
10950 final boolean createNewPackage = (pkgSetting == null);
10951 if (createNewPackage) {
10952 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10953 final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
10954 // REMOVE SharedUserSetting from method; update in a separate call
10955 pkgSetting = Settings.createNewSetting(parsedPackage.getPackageName(),
10956 originalPkgSetting, disabledPkgSetting, realPkgName, sharedUserSetting,
10957 destCodeFile, destResourceFile, parsedPackage.getNativeLibraryRootDir(),
10958 AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage),
10959 AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage),
10960 parsedPackage.getVersionCode(),
10961 PackageInfoWithoutStateUtils.appInfoFlags(parsedPackage),
10962 PackageInfoWithoutStateUtils.appInfoPrivateFlags(parsedPackage),
10963 user, true /*allowInstall*/, instantApp,
10964 virtualPreload, UserManagerService.getInstance(), usesStaticLibraries,
10965 parsedPackage.getUsesStaticLibrariesVersions(), parsedPackage.getMimeGroups());
10967 // make a deep copy to avoid modifying any existing system state.
10968 pkgSetting = new PackageSetting(pkgSetting);
10969 pkgSetting.pkg = parsedPackage;
10971 // REMOVE SharedUserSetting from method; update in a separate call.
10973 // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10974 // secondaryCpuAbi are not known at this point so we always update them
10975 // to null here, only to reset them at a later point.
10976 Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting,
10977 destCodeFile, destResourceFile, parsedPackage.getNativeLibraryDir(),
10978 AndroidPackageUtils.getPrimaryCpuAbi(parsedPackage, pkgSetting),
10979 AndroidPackageUtils.getSecondaryCpuAbi(parsedPackage, pkgSetting),
10980 PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting),
10981 PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting),
10982 UserManagerService.getInstance(),
10983 usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions(),
10984 parsedPackage.getMimeGroups());
10986 if (createNewPackage && originalPkgSetting != null) {
10987 // This is the initial transition from the original package, so,
10988 // fix up the new package's name now. We must do this after looking
10989 // up the package under its new name, so getPackageLP takes care of
10990 // fiddling things correctly.
10991 parsedPackage.setPackageName(originalPkgSetting.name);
10993 // File a report about this.
10994 String msg = "New package " + pkgSetting.realName
10995 + " renamed to replace old package " + pkgSetting.name;
10996 reportSettingsProblem(Log.WARN, msg);
10999 final int userId = (user == null ? UserHandle.USER_SYSTEM : user.getIdentifier());
11000 // for existing packages, change the install state; but, only if it's explicitly specified
11001 if (!createNewPackage) {
11002 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
11003 final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
11004 setInstantAppForUser(injector, pkgSetting, userId, instantApp, fullApp);
11006 // TODO(patb): see if we can do away with disabled check here.
11007 if (disabledPkgSetting != null
11008 || (0 != (scanFlags & SCAN_NEW_INSTALL)
11009 && pkgSetting != null && pkgSetting.isSystem())) {
11010 pkgSetting.getPkgState().setUpdatedSystemApp(true);
11014 .setSeInfo(SELinuxMMAC.getSeInfo(parsedPackage, sharedUserSetting,
11015 injector.getCompatibility()))
11016 .setSeInfoUser(SELinuxUtil.assignSeinfoUser(pkgSetting.readUserState(
11017 userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM : userId)));
11019 if (parsedPackage.isSystem()) {
11020 configurePackageComponents(parsedPackage);
11023 final String cpuAbiOverride = deriveAbiOverride(request.cpuAbiOverride, pkgSetting);
11025 if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
11026 if (needToDeriveAbi) {
11027 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
11028 final boolean extractNativeLibs = !AndroidPackageUtils.isLibrary(parsedPackage);
11029 final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> derivedAbi =
11030 packageAbiHelper.derivePackageAbi(parsedPackage,
11031 pkgSetting.getPkgState().isUpdatedSystemApp(), cpuAbiOverride,
11032 extractNativeLibs);
11033 derivedAbi.first.applyTo(parsedPackage);
11034 derivedAbi.second.applyTo(parsedPackage);
11035 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11037 // Some system apps still use directory structure for native libraries
11038 // in which case we might end up not detecting abi solely based on apk
11039 // structure. Try to detect abi based on directory structure.
11041 String pkgRawPrimaryCpuAbi = AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage);
11042 if (parsedPackage.isSystem() && !pkgSetting.getPkgState().isUpdatedSystemApp() &&
11043 pkgRawPrimaryCpuAbi == null) {
11044 final PackageAbiHelper.Abis abis = packageAbiHelper.getBundledAppAbis(
11046 abis.applyTo(parsedPackage);
11047 abis.applyTo(pkgSetting);
11048 final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
11049 packageAbiHelper.getNativeLibraryPaths(parsedPackage, pkgSetting,
11050 sAppLib32InstallDir);
11051 nativeLibraryPaths.applyTo(parsedPackage);
11054 // This is not a first boot or an upgrade, don't bother deriving the
11055 // ABI during the scan. Instead, trust the value that was stored in the
11056 // package setting.
11057 parsedPackage.setPrimaryCpuAbi(primaryCpuAbiFromSettings)
11058 .setSecondaryCpuAbi(secondaryCpuAbiFromSettings);
11060 final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
11061 packageAbiHelper.getNativeLibraryPaths(parsedPackage,
11062 pkgSetting, sAppLib32InstallDir);
11063 nativeLibraryPaths.applyTo(parsedPackage);
11065 if (DEBUG_ABI_SELECTION) {
11066 Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
11067 parsedPackage.getPackageName() + " " +
11068 AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage)
11070 + AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage));
11074 if ((scanFlags & SCAN_MOVE) != 0) {
11075 // We haven't run dex-opt for this move (since we've moved the compiled output too)
11076 // but we already have this packages package info in the PackageSetting. We just
11077 // use that and derive the native library path based on the new codepath.
11078 parsedPackage.setPrimaryCpuAbi(pkgSetting.primaryCpuAbiString)
11079 .setSecondaryCpuAbi(pkgSetting.secondaryCpuAbiString);
11082 // Set native library paths again. For moves, the path will be updated based on the
11083 // ABIs we've determined above. For non-moves, the path will be updated based on the
11084 // ABIs we determined during compilation, but the path will depend on the final
11085 // package path (after the rename away from the stage path).
11086 final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
11087 packageAbiHelper.getNativeLibraryPaths(parsedPackage, pkgSetting,
11088 sAppLib32InstallDir);
11089 nativeLibraryPaths.applyTo(parsedPackage);
11092 // This is a special case for the "system" package, where the ABI is
11093 // dictated by the zygote configuration (and init.rc). We should keep track
11094 // of this ABI so that we can deal with "normal" applications that run under
11095 // the same UID correctly.
11096 if (isPlatformPackage) {
11097 parsedPackage.setPrimaryCpuAbi(VMRuntime.getRuntime().is64Bit() ?
11098 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]);
11101 // If there's a mismatch between the abi-override in the package setting
11102 // and the abiOverride specified for the install. Warn about this because we
11103 // would've already compiled the app without taking the package setting into
11105 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
11106 if (cpuAbiOverride == null) {
11107 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
11108 " for package " + parsedPackage.getPackageName());
11112 pkgSetting.primaryCpuAbiString = AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage);
11113 pkgSetting.secondaryCpuAbiString = AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage);
11114 pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
11116 if (DEBUG_ABI_SELECTION) {
11117 Slog.d(TAG, "Resolved nativeLibraryRoot for " + parsedPackage.getPackageName()
11118 + " to root=" + parsedPackage.getNativeLibraryRootDir() + ", isa="
11119 + parsedPackage.isNativeLibraryRootRequiresIsa());
11122 // Push the derived path down into PackageSettings so we know what to
11123 // clean up at uninstall time.
11124 pkgSetting.legacyNativeLibraryPathString = parsedPackage.getNativeLibraryRootDir();
11126 if (DEBUG_ABI_SELECTION) {
11127 Log.d(TAG, "Abis for package[" + parsedPackage.getPackageName() + "] are" +
11128 " primary=" + AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage) +
11129 " secondary=" + AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage));
11132 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
11133 // We don't do this here during boot because we can do it all
11134 // at once after scanning all existing packages.
11136 // We also do this *before* we perform dexopt on this package, so that
11137 // we can avoid redundant dexopts, and also to make sure we've got the
11138 // code and package path correct.
11139 changedAbiCodePath = applyAdjustedAbiToSharedUser(pkgSetting.sharedUser, parsedPackage,
11140 packageAbiHelper.getAdjustedAbiForSharedUser(
11141 pkgSetting.sharedUser.packages, parsedPackage));
11144 parsedPackage.setFactoryTest(isUnderFactoryTest && parsedPackage.getRequestedPermissions()
11145 .contains(android.Manifest.permission.FACTORY_TEST));
11147 if (parsedPackage.isSystem()) {
11148 pkgSetting.setIsOrphaned(true);
11151 // Take care of first install / last update times.
11152 final long scanFileTime = getLastModifiedTime(parsedPackage);
11153 if (currentTime != 0) {
11154 if (pkgSetting.firstInstallTime == 0) {
11155 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
11156 } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
11157 pkgSetting.lastUpdateTime = currentTime;
11159 } else if (pkgSetting.firstInstallTime == 0) {
11160 // We need *something*. Take time time stamp of the file.
11161 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
11162 } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
11163 if (scanFileTime != pkgSetting.timeStamp) {
11164 // A package on the system image has changed; consider this
11165 // to be an update.
11166 pkgSetting.lastUpdateTime = scanFileTime;
11169 pkgSetting.setTimeStamp(scanFileTime);
11170 // TODO(b/135203078): Remove, move to constructor
11171 pkgSetting.pkg = parsedPackage;
11172 pkgSetting.pkgFlags = PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting);
11173 pkgSetting.pkgPrivateFlags =
11174 PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting);
11175 if (parsedPackage.getLongVersionCode() != pkgSetting.versionCode) {
11176 pkgSetting.versionCode = parsedPackage.getLongVersionCode();
11178 // Update volume if needed
11179 final String volumeUuid = parsedPackage.getVolumeUuid();
11180 if (!Objects.equals(volumeUuid, pkgSetting.volumeUuid)) {
11181 Slog.i(PackageManagerService.TAG,
11182 "Update" + (pkgSetting.isSystem() ? " system" : "")
11183 + " package " + parsedPackage.getPackageName()
11184 + " volume from " + pkgSetting.volumeUuid
11185 + " to " + volumeUuid);
11186 pkgSetting.volumeUuid = volumeUuid;
11189 SharedLibraryInfo staticSharedLibraryInfo = null;
11190 if (!TextUtils.isEmpty(parsedPackage.getStaticSharedLibName())) {
11191 staticSharedLibraryInfo =
11192 AndroidPackageUtils.createSharedLibraryForStatic(parsedPackage);
11194 List<SharedLibraryInfo> dynamicSharedLibraryInfos = null;
11195 if (!ArrayUtils.isEmpty(parsedPackage.getLibraryNames())) {
11196 dynamicSharedLibraryInfos = new ArrayList<>(parsedPackage.getLibraryNames().size());
11197 for (String name : parsedPackage.getLibraryNames()) {
11198 dynamicSharedLibraryInfos.add(
11199 AndroidPackageUtils.createSharedLibraryForDynamic(parsedPackage, name));
11203 return new ScanResult(request, true, pkgSetting, changedAbiCodePath,
11204 !createNewPackage /* existingSettingCopied */, staticSharedLibraryInfo,
11205 dynamicSharedLibraryInfos);
11209 * Returns {@code true} if the given file contains code. Otherwise {@code false}.
11211 private static boolean apkHasCode(String fileName) {
11212 StrictJarFile jarFile = null;
11214 jarFile = new StrictJarFile(fileName,
11215 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
11216 return jarFile.findEntry("classes.dex") != null;
11217 } catch (IOException ignore) {
11220 if (jarFile != null) {
11223 } catch (IOException ignore) {}
11229 * Enforces code policy for the package. This ensures that if an APK has
11230 * declared hasCode="true" in its manifest that the APK actually contains
11233 * @throws PackageManagerException If bytecode could not be found when it should exist
11235 private static void assertCodePolicy(AndroidPackage pkg)
11236 throws PackageManagerException {
11237 final boolean shouldHaveCode = pkg.isHasCode();
11238 if (shouldHaveCode && !apkHasCode(pkg.getBaseCodePath())) {
11239 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
11240 "Package " + pkg.getBaseCodePath() + " code is missing");
11243 if (!ArrayUtils.isEmpty(pkg.getSplitCodePaths())) {
11244 for (int i = 0; i < pkg.getSplitCodePaths().length; i++) {
11245 final boolean splitShouldHaveCode =
11246 (pkg.getSplitFlags()[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
11247 if (splitShouldHaveCode && !apkHasCode(pkg.getSplitCodePaths()[i])) {
11248 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
11249 "Package " + pkg.getSplitCodePaths()[i] + " code is missing");
11256 * Applies policy to the parsed package based upon the given policy flags.
11257 * Ensures the package is in a good state.
11259 * Implementation detail: This method must NOT have any side effect. It would
11260 * ideally be static, but, it requires locks to read system state.
11262 private static void applyPolicy(ParsedPackage parsedPackage, final @ParseFlags int parseFlags,
11263 final @ScanFlags int scanFlags, AndroidPackage platformPkg,
11264 boolean isUpdatedSystemApp) {
11265 if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
11266 parsedPackage.setSystem(true);
11267 // TODO(b/135203078): Can this be done in PackageParser? Or just inferred when the flag
11268 // is set during parse.
11269 if (parsedPackage.isDirectBootAware()) {
11270 parsedPackage.setAllComponentsDirectBootAware(true);
11272 if (compressedFileExists(parsedPackage.getCodePath())) {
11273 parsedPackage.setStub(true);
11277 // non system apps can't be flagged as core
11279 // clear flags not applicable to regular apps
11280 .setPersistent(false)
11281 .setDefaultToDeviceProtectedStorage(false)
11282 .setDirectBootAware(false)
11283 // non system apps can't have permission priority
11284 .capPermissionPriorities();
11286 if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
11288 .clearProtectedBroadcasts()
11289 .markNotActivitiesAsNotExportedIfSingleUser();
11292 parsedPackage.setPrivileged((scanFlags & SCAN_AS_PRIVILEGED) != 0)
11293 .setOem((scanFlags & SCAN_AS_OEM) != 0)
11294 .setVendor((scanFlags & SCAN_AS_VENDOR) != 0)
11295 .setProduct((scanFlags & SCAN_AS_PRODUCT) != 0)
11296 .setSystemExt((scanFlags & SCAN_AS_SYSTEM_EXT) != 0)
11297 .setOdm((scanFlags & SCAN_AS_ODM) != 0);
11299 // Check if the package is signed with the same key as the platform package.
11300 parsedPackage.setSignedWithPlatformKey(
11301 (PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())
11302 || (platformPkg != null && compareSignatures(
11303 platformPkg.getSigningDetails().signatures,
11304 parsedPackage.getSigningDetails().signatures
11305 ) == PackageManager.SIGNATURE_MATCH))
11308 if (!parsedPackage.isSystem()) {
11309 // Only system apps can use these features.
11310 parsedPackage.clearOriginalPackages()
11311 .setRealPackage(null)
11312 .clearAdoptPermissions();
11315 PackageBackwardCompatibility.modifySharedLibraries(parsedPackage, isUpdatedSystemApp);
11318 private static @NonNull <T> T assertNotNull(@Nullable T object, String message)
11319 throws PackageManagerException {
11320 if (object == null) {
11321 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, message);
11326 private <T extends ParsedMainComponent>
11327 void assertPackageProcesses(AndroidPackage pkg, List<T> components,
11328 Map<String, ParsedProcess> procs, String compName)
11329 throws PackageManagerException {
11330 if (components == null) {
11333 for (int i = components.size() - 1; i >= 0; i--) {
11334 final ParsedMainComponent component = components.get(i);
11335 if (!procs.containsKey(component.getProcessName())) {
11336 throw new PackageManagerException(
11337 INSTALL_FAILED_PROCESS_NOT_DEFINED,
11338 "Can't install because " + compName + " " + component.getClassName()
11339 + "'s process attribute " + component.getProcessName()
11340 + " (in package " + pkg.getPackageName()
11341 + ") is not included in the <processes> list");
11347 * Asserts the parsed package is valid according to the given policy. If the
11348 * package is invalid, for whatever reason, throws {@link PackageManagerException}.
11350 * Implementation detail: This method must NOT have any side effects. It would
11351 * ideally be static, but, it requires locks to read system state.
11353 * @throws PackageManagerException If the package fails any of the validation checks
11355 private void assertPackageIsValid(AndroidPackage pkg, final @ParseFlags int parseFlags,
11356 final @ScanFlags int scanFlags)
11357 throws PackageManagerException {
11358 if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
11359 assertCodePolicy(pkg);
11362 if (pkg.getCodePath() == null) {
11363 // Bail out. The resource and code paths haven't been set.
11364 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
11365 "Code and resource paths haven't been set correctly");
11368 // Check that there is an APEX package with the same name only during install/first boot
11370 final boolean isUserInstall = (scanFlags & SCAN_BOOTING) == 0;
11371 final boolean isFirstBootOrUpgrade = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
11372 if ((isUserInstall || isFirstBootOrUpgrade)
11373 && mApexManager.isApexPackage(pkg.getPackageName())) {
11374 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11375 pkg.getPackageName()
11376 + " is an APEX package and can't be installed as an APK.");
11379 // Make sure we're not adding any bogus keyset info
11380 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
11381 ksms.assertScannedPackageValid(pkg);
11383 synchronized (mLock) {
11384 // The special "android" package can only be defined once
11385 if (pkg.getPackageName().equals("android")) {
11386 if (mAndroidApplication != null) {
11387 Slog.w(TAG, "*************************************************");
11388 Slog.w(TAG, "Core android package being redefined. Skipping.");
11389 Slog.w(TAG, " codePath=" + pkg.getCodePath());
11390 Slog.w(TAG, "*************************************************");
11391 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11392 "Core android package being redefined. Skipping.");
11396 // A package name must be unique; don't allow duplicates
11397 if ((scanFlags & SCAN_NEW_INSTALL) == 0
11398 && mPackages.containsKey(pkg.getPackageName())) {
11399 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11400 "Application package " + pkg.getPackageName()
11401 + " already installed. Skipping duplicate.");
11404 if (pkg.isStaticSharedLibrary()) {
11405 // Static libs have a synthetic package name containing the version
11406 // but we still want the base name to be unique.
11407 if ((scanFlags & SCAN_NEW_INSTALL) == 0
11408 && mPackages.containsKey(pkg.getManifestPackageName())) {
11409 throw new PackageManagerException(
11410 "Duplicate static shared lib provider package");
11413 // Static shared libraries should have at least O target SDK
11414 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
11415 throw new PackageManagerException(
11416 "Packages declaring static-shared libs must target O SDK or higher");
11419 // Package declaring static a shared lib cannot be instant apps
11420 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11421 throw new PackageManagerException(
11422 "Packages declaring static-shared libs cannot be instant apps");
11425 // Package declaring static a shared lib cannot be renamed since the package
11426 // name is synthetic and apps can't code around package manager internals.
11427 if (!ArrayUtils.isEmpty(pkg.getOriginalPackages())) {
11428 throw new PackageManagerException(
11429 "Packages declaring static-shared libs cannot be renamed");
11432 // Package declaring static a shared lib cannot declare dynamic libs
11433 if (!ArrayUtils.isEmpty(pkg.getLibraryNames())) {
11434 throw new PackageManagerException(
11435 "Packages declaring static-shared libs cannot declare dynamic libs");
11438 // Package declaring static a shared lib cannot declare shared users
11439 if (pkg.getSharedUserId() != null) {
11440 throw new PackageManagerException(
11441 "Packages declaring static-shared libs cannot declare shared users");
11444 // Static shared libs cannot declare activities
11445 if (!pkg.getActivities().isEmpty()) {
11446 throw new PackageManagerException(
11447 "Static shared libs cannot declare activities");
11450 // Static shared libs cannot declare services
11451 if (!pkg.getServices().isEmpty()) {
11452 throw new PackageManagerException(
11453 "Static shared libs cannot declare services");
11456 // Static shared libs cannot declare providers
11457 if (!pkg.getProviders().isEmpty()) {
11458 throw new PackageManagerException(
11459 "Static shared libs cannot declare content providers");
11462 // Static shared libs cannot declare receivers
11463 if (!pkg.getReceivers().isEmpty()) {
11464 throw new PackageManagerException(
11465 "Static shared libs cannot declare broadcast receivers");
11468 // Static shared libs cannot declare permission groups
11469 if (!pkg.getPermissionGroups().isEmpty()) {
11470 throw new PackageManagerException(
11471 "Static shared libs cannot declare permission groups");
11474 // Static shared libs cannot declare features
11475 if (!pkg.getFeatures().isEmpty()) {
11476 throw new PackageManagerException(
11477 "Static shared libs cannot declare features");
11480 // Static shared libs cannot declare permissions
11481 if (!pkg.getPermissions().isEmpty()) {
11482 throw new PackageManagerException(
11483 "Static shared libs cannot declare permissions");
11486 // Static shared libs cannot declare protected broadcasts
11487 if (!pkg.getProtectedBroadcasts().isEmpty()) {
11488 throw new PackageManagerException(
11489 "Static shared libs cannot declare protected broadcasts");
11492 // Static shared libs cannot be overlay targets
11493 if (pkg.getOverlayTarget() != null) {
11494 throw new PackageManagerException(
11495 "Static shared libs cannot be overlay targets");
11498 // The version codes must be ordered as lib versions
11499 long minVersionCode = Long.MIN_VALUE;
11500 long maxVersionCode = Long.MAX_VALUE;
11502 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(
11503 pkg.getStaticSharedLibName());
11504 if (versionedLib != null) {
11505 final int versionCount = versionedLib.size();
11506 for (int i = 0; i < versionCount; i++) {
11507 SharedLibraryInfo libInfo = versionedLib.valueAt(i);
11508 final long libVersionCode = libInfo.getDeclaringPackage()
11509 .getLongVersionCode();
11510 if (libInfo.getLongVersion() < pkg.getStaticSharedLibVersion()) {
11511 minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
11512 } else if (libInfo.getLongVersion()
11513 > pkg.getStaticSharedLibVersion()) {
11514 maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
11516 minVersionCode = maxVersionCode = libVersionCode;
11521 if (pkg.getLongVersionCode() < minVersionCode
11522 || pkg.getLongVersionCode() > maxVersionCode) {
11523 throw new PackageManagerException("Static shared"
11524 + " lib version codes must be ordered as lib versions");
11528 // If we're only installing presumed-existing packages, require that the
11529 // scanned APK is both already known and at the path previously established
11530 // for it. Previously unknown packages we pick up normally, but if we have an
11531 // a priori expectation about this package's install presence, enforce it.
11532 // With a singular exception for new system packages. When an OTA contains
11533 // a new system package, we allow the codepath to change from a system location
11534 // to the user-installed location. If we don't allow this change, any newer,
11535 // user-installed version of the application will be ignored.
11536 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
11537 if (mExpectingBetter.containsKey(pkg.getPackageName())) {
11538 logCriticalInfo(Log.WARN,
11539 "Relax SCAN_REQUIRE_KNOWN requirement for package "
11540 + pkg.getPackageName());
11542 PackageSetting known = mSettings.getPackageLPr(pkg.getPackageName());
11543 if (known != null) {
11544 if (DEBUG_PACKAGE_SCANNING) {
11545 Log.d(TAG, "Examining " + pkg.getCodePath()
11546 + " and requiring known paths " + known.codePathString
11547 + " & " + known.resourcePathString);
11549 if (!pkg.getCodePath().equals(known.codePathString)
11550 || !pkg.getCodePath().equals(known.resourcePathString)) {
11551 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
11552 "Application package " + pkg.getPackageName()
11553 + " found at " + pkg.getCodePath()
11554 + " but expected at " + known.codePathString
11558 throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
11559 "Application package " + pkg.getPackageName()
11560 + " not found; ignoring.");
11565 // Verify that this new package doesn't have any content providers
11566 // that conflict with existing packages. Only do this if the
11567 // package isn't already installed, since we don't want to break
11568 // things that are installed.
11569 if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
11570 mComponentResolver.assertProvidersNotDefined(pkg);
11573 // If this package has defined explicit processes, then ensure that these are
11574 // the only processes used by its components.
11575 final Map<String, ParsedProcess> procs = pkg.getProcesses();
11576 if (!procs.isEmpty()) {
11577 if (!procs.containsKey(pkg.getProcessName())) {
11578 throw new PackageManagerException(
11579 INSTALL_FAILED_PROCESS_NOT_DEFINED,
11580 "Can't install because application tag's process attribute "
11581 + pkg.getProcessName()
11582 + " (in package " + pkg.getPackageName()
11583 + ") is not included in the <processes> list");
11585 assertPackageProcesses(pkg, pkg.getActivities(), procs, "activity");
11586 assertPackageProcesses(pkg, pkg.getServices(), procs, "service");
11587 assertPackageProcesses(pkg, pkg.getReceivers(), procs, "receiver");
11588 assertPackageProcesses(pkg, pkg.getProviders(), procs, "provider");
11591 // Verify that packages sharing a user with a privileged app are marked as privileged.
11592 if (!pkg.isPrivileged() && (pkg.getSharedUserId() != null)) {
11593 SharedUserSetting sharedUserSetting = null;
11595 sharedUserSetting = mSettings.getSharedUserLPw(pkg.getSharedUserId(),
11597 } catch (PackageManagerException ignore) {
11599 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
11600 // Exempt SharedUsers signed with the platform key.
11601 PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
11602 if ((platformPkgSetting.signatures.mSigningDetails
11603 != PackageParser.SigningDetails.UNKNOWN)
11604 && (compareSignatures(
11605 platformPkgSetting.signatures.mSigningDetails.signatures,
11606 pkg.getSigningDetails().signatures)
11607 != PackageManager.SIGNATURE_MATCH)) {
11608 throw new PackageManagerException("Apps that share a user with a " +
11609 "privileged app must themselves be marked as privileged. " +
11610 pkg.getPackageName() + " shares privileged user " +
11611 pkg.getSharedUserId() + ".");
11616 // Apply policies specific for runtime resource overlays (RROs).
11617 if (pkg.getOverlayTarget() != null) {
11618 // System overlays have some restrictions on their use of the 'static' state.
11619 if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
11620 // We are scanning a system overlay. This can be the first scan of the
11621 // system/vendor/oem partition, or an update to the system overlay.
11622 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11623 // This must be an update to a system overlay. Immutable overlays cannot be
11625 Objects.requireNonNull(mOverlayConfig,
11626 "Parsing non-system dir before overlay configs are initialized");
11627 if (!mOverlayConfig.isMutable(pkg.getPackageName())) {
11628 throw new PackageManagerException("Overlay "
11629 + pkg.getPackageName()
11630 + " is static and cannot be upgraded.");
11634 // A non-preloaded overlay packages must have targetSdkVersion >= Q, or be
11635 // signed with the platform certificate. Check this in increasing order of
11636 // computational cost.
11637 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.Q) {
11638 final PackageSetting platformPkgSetting =
11639 mSettings.getPackageLPr("android");
11640 if ((platformPkgSetting.signatures.mSigningDetails
11641 != PackageParser.SigningDetails.UNKNOWN)
11642 && (compareSignatures(
11643 platformPkgSetting.signatures.mSigningDetails.signatures,
11644 pkg.getSigningDetails().signatures)
11645 != PackageManager.SIGNATURE_MATCH)) {
11646 throw new PackageManagerException("Overlay "
11647 + pkg.getPackageName()
11648 + " must target Q or later, "
11649 + "or be signed with the platform certificate");
11653 // A non-preloaded overlay package, without <overlay android:targetName>, will
11654 // only be used if it is signed with the same certificate as its target. If the
11655 // target is already installed, check this here to augment the last line of
11656 // defence which is OMS.
11657 if (pkg.getOverlayTargetName() == null) {
11658 final PackageSetting targetPkgSetting =
11659 mSettings.getPackageLPr(pkg.getOverlayTarget());
11660 if (targetPkgSetting != null) {
11661 if ((targetPkgSetting.signatures.mSigningDetails
11662 != PackageParser.SigningDetails.UNKNOWN)
11663 && (compareSignatures(
11664 targetPkgSetting.signatures.mSigningDetails.signatures,
11665 pkg.getSigningDetails().signatures)
11666 != PackageManager.SIGNATURE_MATCH)) {
11667 throw new PackageManagerException("Overlay "
11668 + pkg.getPackageName() + " and target "
11669 + pkg.getOverlayTarget() + " signed with"
11670 + " different certificates, and the overlay lacks"
11671 + " <overlay android:targetName>");
11678 // Ensure the package is signed with at least the minimum signature scheme version
11679 // required for its target SDK.
11680 int minSignatureSchemeVersion =
11681 ApkSignatureVerifier.getMinimumSignatureSchemeVersionForTargetSdk(
11682 pkg.getTargetSdkVersion());
11683 if (pkg.getSigningDetails().signatureSchemeVersion < minSignatureSchemeVersion) {
11684 throw new PackageManagerException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
11685 "No signature found in package of version " + minSignatureSchemeVersion
11686 + " or newer for package " + pkg.getPackageName());
11691 @GuardedBy("mLock")
11692 private boolean addBuiltInSharedLibraryLocked(String path, String name) {
11693 if (nonStaticSharedLibExistsLocked(name)) {
11697 SharedLibraryInfo libraryInfo = new SharedLibraryInfo(path, null, null, name,
11698 (long) SharedLibraryInfo.VERSION_UNDEFINED, SharedLibraryInfo.TYPE_BUILTIN,
11699 new VersionedPackage(PLATFORM_PACKAGE_NAME, (long) 0),
11702 commitSharedLibraryInfoLocked(libraryInfo);
11706 @GuardedBy("mLock")
11707 private boolean nonStaticSharedLibExistsLocked(String name) {
11708 return sharedLibExists(name, SharedLibraryInfo.VERSION_UNDEFINED, mSharedLibraries);
11711 private static boolean sharedLibExists(final String name, final long version,
11712 Map<String, LongSparseArray<SharedLibraryInfo>> librarySource) {
11713 LongSparseArray<SharedLibraryInfo> versionedLib = librarySource.get(name);
11714 if (versionedLib != null && versionedLib.indexOfKey(version) >= 0) {
11720 @GuardedBy("mLock")
11721 private void commitSharedLibraryInfoLocked(SharedLibraryInfo libraryInfo) {
11722 final String name = libraryInfo.getName();
11723 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(name);
11724 if (versionedLib == null) {
11725 versionedLib = new LongSparseArray<>();
11726 mSharedLibraries.put(name, versionedLib);
11728 final String declaringPackageName = libraryInfo.getDeclaringPackage().getPackageName();
11729 if (libraryInfo.getType() == SharedLibraryInfo.TYPE_STATIC) {
11730 mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
11732 versionedLib.put(libraryInfo.getLongVersion(), libraryInfo);
11735 private boolean removeSharedLibraryLPw(String name, long version) {
11736 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(name);
11737 if (versionedLib == null) {
11740 final int libIdx = versionedLib.indexOfKey(version);
11744 SharedLibraryInfo libraryInfo = versionedLib.valueAt(libIdx);
11746 // Remove the shared library overlays from its dependent packages.
11747 for (int currentUserId : UserManagerService.getInstance().getUserIds()) {
11748 final List<VersionedPackage> dependents = getPackagesUsingSharedLibraryLPr(
11749 libraryInfo, 0, currentUserId);
11750 if (dependents == null) {
11753 for (VersionedPackage dependentPackage : dependents) {
11754 final PackageSetting ps = mSettings.mPackages.get(
11755 dependentPackage.getPackageName());
11757 ps.setOverlayPathsForLibrary(libraryInfo.getName(), null, currentUserId);
11762 versionedLib.remove(version);
11763 if (versionedLib.size() <= 0) {
11764 mSharedLibraries.remove(name);
11765 if (libraryInfo.getType() == SharedLibraryInfo.TYPE_STATIC) {
11766 mStaticLibsByDeclaringPackage.remove(libraryInfo.getDeclaringPackage()
11767 .getPackageName());
11774 * Adds a scanned package to the system. When this method is finished, the package will
11775 * be available for query, resolution, etc...
11777 private void commitPackageSettings(AndroidPackage pkg,
11778 @Nullable AndroidPackage oldPkg, PackageSetting pkgSetting,
11779 final @ScanFlags int scanFlags, boolean chatty, ReconciledPackage reconciledPkg) {
11780 final String pkgName = pkg.getPackageName();
11781 if (mCustomResolverComponentName != null &&
11782 mCustomResolverComponentName.getPackageName().equals(pkg.getPackageName())) {
11783 setUpCustomResolverActivity(pkg, pkgSetting);
11786 if (pkg.getPackageName().equals("android")) {
11787 synchronized (mLock) {
11788 // Set up information for our fall-back user intent resolution activity.
11789 mPlatformPackage = pkg;
11791 // The instance stored in PackageManagerService is special cased to be non-user
11792 // specific, so initialize all the needed fields here.
11793 mAndroidApplication = pkg.toAppInfoWithoutState();
11794 mAndroidApplication.flags = PackageInfoUtils.appInfoFlags(pkg, pkgSetting);
11795 mAndroidApplication.privateFlags =
11796 PackageInfoUtils.appInfoPrivateFlags(pkg, pkgSetting);
11797 mAndroidApplication.initForUser(UserHandle.USER_SYSTEM);
11799 if (!mResolverReplaced) {
11800 mResolveActivity.applicationInfo = mAndroidApplication;
11801 mResolveActivity.name = ResolverActivity.class.getName();
11802 mResolveActivity.packageName = mAndroidApplication.packageName;
11803 mResolveActivity.processName = "system:ui";
11804 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11805 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
11806 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
11807 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
11808 mResolveActivity.exported = true;
11809 mResolveActivity.enabled = true;
11810 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
11811 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
11812 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
11813 | ActivityInfo.CONFIG_SCREEN_LAYOUT
11814 | ActivityInfo.CONFIG_ORIENTATION
11815 | ActivityInfo.CONFIG_KEYBOARD
11816 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
11817 mResolveInfo.activityInfo = mResolveActivity;
11818 mResolveInfo.priority = 0;
11819 mResolveInfo.preferredOrder = 0;
11820 mResolveInfo.match = 0;
11821 mResolveComponentName = new ComponentName(
11822 mAndroidApplication.packageName, mResolveActivity.name);
11827 ArrayList<AndroidPackage> clientLibPkgs = null;
11829 synchronized (mLock) {
11830 if (!ArrayUtils.isEmpty(reconciledPkg.allowedSharedLibraryInfos)) {
11831 for (SharedLibraryInfo info : reconciledPkg.allowedSharedLibraryInfos) {
11832 commitSharedLibraryInfoLocked(info);
11834 final Map<String, AndroidPackage> combinedSigningDetails =
11835 reconciledPkg.getCombinedAvailablePackages();
11837 // Shared libraries for the package need to be updated.
11838 updateSharedLibrariesLocked(pkg, pkgSetting, null, null,
11839 combinedSigningDetails);
11840 } catch (PackageManagerException e) {
11841 Slog.e(TAG, "updateSharedLibrariesLPr failed: ", e);
11843 // Update all applications that use this library. Skip when booting
11844 // since this will be done after all packages are scaned.
11845 if ((scanFlags & SCAN_BOOTING) == 0) {
11846 clientLibPkgs = updateAllSharedLibrariesLocked(pkg, pkgSetting,
11847 combinedSigningDetails);
11851 if (reconciledPkg.installResult != null) {
11852 reconciledPkg.installResult.libraryConsumers = clientLibPkgs;
11855 if ((scanFlags & SCAN_BOOTING) != 0) {
11856 // No apps can run during boot scan, so they don't need to be frozen
11857 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
11858 // Caller asked to not kill app, so it's probably not frozen
11859 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
11860 // Caller asked us to ignore frozen check for some reason; they
11861 // probably didn't know the package name
11863 // We're doing major surgery on this package, so it better be frozen
11864 // right now to keep it from launching
11865 checkPackageFrozen(pkgName);
11868 // Also need to kill any apps that are dependent on the library.
11869 if (clientLibPkgs != null) {
11870 for (int i=0; i<clientLibPkgs.size(); i++) {
11871 AndroidPackage clientPkg = clientLibPkgs.get(i);
11872 killApplication(clientPkg.getPackageName(),
11873 clientPkg.getUid(), "update lib");
11878 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11880 synchronized (mLock) {
11881 // We don't expect installation to fail beyond this point
11883 // Add the new setting to mSettings
11884 mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11885 // Add the new setting to mPackages
11886 mPackages.put(pkg.getPackageName(), pkg);
11887 if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
11888 mApexManager.registerApkInApex(pkg);
11891 // Add the package's KeySets to the global KeySetManagerService
11892 KeySetManagerService ksms = mSettings.mKeySetManagerService;
11893 ksms.addScannedPackageLPw(pkg);
11895 mComponentResolver.addAllComponents(pkg, chatty);
11896 mAppsFilter.addPackage(pkgSetting, mSettings.mPackages);
11898 // Don't allow ephemeral applications to define new permissions groups.
11899 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11900 Slog.w(TAG, "Permission groups from package " + pkg.getPackageName()
11901 + " ignored: instant apps cannot define new permission groups.");
11903 mPermissionManager.addAllPermissionGroups(pkg, chatty);
11906 // Don't allow ephemeral applications to define new permissions.
11907 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11908 Slog.w(TAG, "Permissions from package " + pkg.getPackageName()
11909 + " ignored: instant apps cannot define new permissions.");
11911 mPermissionManager.addAllPermissions(pkg, chatty);
11914 int collectionSize = ArrayUtils.size(pkg.getInstrumentations());
11915 StringBuilder r = null;
11917 for (i = 0; i < collectionSize; i++) {
11918 ParsedInstrumentation a = pkg.getInstrumentations().get(i);
11919 a.setPackageName(pkg.getPackageName());
11920 mInstrumentation.put(a.getComponentName(), a);
11923 r = new StringBuilder(256);
11927 r.append(a.getName());
11931 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r);
11934 if (!pkg.getProtectedBroadcasts().isEmpty()) {
11935 synchronized (mProtectedBroadcasts) {
11936 mProtectedBroadcasts.addAll(pkg.getProtectedBroadcasts());
11940 if (oldPkg != null) {
11941 // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
11942 // revoke callbacks from this method might need to kill apps which need the
11943 // mPackages lock on a different thread. This would dead lock.
11945 // Hence create a copy of all package names and pass it into
11946 // revokeRuntimePermissionsIfGroupChanged. Only for those permissions might get
11947 // revoked. If a new package is added before the async code runs the permission
11948 // won't be granted yet, hence new packages are no problem.
11949 final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
11951 AsyncTask.execute(() ->
11952 mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg,
11957 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11960 private void setUpCustomResolverActivity(AndroidPackage pkg, PackageSetting pkgSetting) {
11961 synchronized (mLock) {
11962 mResolverReplaced = true;
11964 // The instance created in PackageManagerService is special cased to be non-user
11965 // specific, so initialize all the needed fields here.
11966 ApplicationInfo appInfo = pkg.toAppInfoWithoutState();
11967 appInfo.flags = PackageInfoUtils.appInfoFlags(pkg, pkgSetting);
11968 appInfo.privateFlags =
11969 PackageInfoUtils.appInfoPrivateFlags(pkg, pkgSetting);
11970 appInfo.initForUser(UserHandle.USER_SYSTEM);
11972 // Set up information for custom user intent resolution activity.
11973 mResolveActivity.applicationInfo = appInfo;
11974 mResolveActivity.name = mCustomResolverComponentName.getClassName();
11975 mResolveActivity.packageName = pkg.getPackageName();
11976 mResolveActivity.processName = pkg.getProcessName();
11977 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11978 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11979 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11980 mResolveActivity.theme = 0;
11981 mResolveActivity.exported = true;
11982 mResolveActivity.enabled = true;
11983 mResolveInfo.activityInfo = mResolveActivity;
11984 mResolveInfo.priority = 0;
11985 mResolveInfo.preferredOrder = 0;
11986 mResolveInfo.match = 0;
11987 mResolveComponentName = mCustomResolverComponentName;
11988 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11989 mResolveComponentName);
11993 private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11994 if (installerActivity == null) {
11995 if (DEBUG_INSTANT) {
11996 Slog.d(TAG, "Clear ephemeral installer activity");
11998 mInstantAppInstallerActivity = null;
12002 if (DEBUG_INSTANT) {
12003 Slog.d(TAG, "Set ephemeral installer activity: "
12004 + installerActivity.getComponentName());
12006 // Set up information for ephemeral installer activity
12007 mInstantAppInstallerActivity = installerActivity;
12008 mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
12009 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12010 mInstantAppInstallerActivity.exported = true;
12011 mInstantAppInstallerActivity.enabled = true;
12012 mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
12013 mInstantAppInstallerInfo.priority = 1;
12014 mInstantAppInstallerInfo.preferredOrder = 1;
12015 mInstantAppInstallerInfo.isDefault = true;
12016 mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
12017 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
12020 private void killApplication(String pkgName, @AppIdInt int appId, String reason) {
12021 killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
12024 private void killApplication(String pkgName, @AppIdInt int appId,
12025 @UserIdInt int userId, String reason) {
12026 // Request the ActivityManager to kill the process(only for existing packages)
12027 // so that we do not end up in a confused state while the user is still using the older
12028 // version of the application while the new one gets installed.
12029 final long token = Binder.clearCallingIdentity();
12031 IActivityManager am = ActivityManager.getService();
12034 am.killApplication(pkgName, appId, userId, reason);
12035 } catch (RemoteException e) {
12039 Binder.restoreCallingIdentity(token);
12043 private void removePackageLI(AndroidPackage pkg, boolean chatty) {
12044 // Remove the parent package setting
12045 PackageSetting ps = getPackageSetting(pkg.getPackageName());
12047 removePackageLI(ps.name, chatty);
12048 } else if (DEBUG_REMOVE && chatty) {
12049 Log.d(TAG, "Not removing package " + pkg.getPackageName() + "; mExtras == null");
12053 void removePackageLI(String packageName, boolean chatty) {
12054 if (DEBUG_INSTALL) {
12056 Log.d(TAG, "Removing package " + packageName);
12060 synchronized (mLock) {
12061 final AndroidPackage removedPackage = mPackages.remove(packageName);
12062 if (removedPackage != null) {
12063 cleanPackageDataStructuresLILPw(removedPackage, chatty);
12068 void cleanPackageDataStructuresLILPw(AndroidPackage pkg, boolean chatty) {
12069 mComponentResolver.removeAllComponents(pkg, chatty);
12070 mAppsFilter.removePackage(getPackageSetting(pkg.getPackageName()),
12071 mInjector.getUserManagerInternal().getUserIds(), mSettings.mPackages);
12072 mPermissionManager.removeAllPermissions(pkg, chatty);
12074 final int instrumentationSize = ArrayUtils.size(pkg.getInstrumentations());
12075 StringBuilder r = null;
12077 for (i = 0; i < instrumentationSize; i++) {
12078 ParsedInstrumentation a = pkg.getInstrumentations().get(i);
12079 mInstrumentation.remove(a.getComponentName());
12080 if (DEBUG_REMOVE && chatty) {
12082 r = new StringBuilder(256);
12086 r.append(a.getName());
12090 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
12094 if (pkg.isSystem()) {
12095 // Only system apps can hold shared libraries.
12096 final int libraryNamesSize = pkg.getLibraryNames().size();
12097 for (i = 0; i < libraryNamesSize; i++) {
12098 String name = pkg.getLibraryNames().get(i);
12099 if (removeSharedLibraryLPw(name, 0)) {
12100 if (DEBUG_REMOVE && chatty) {
12102 r = new StringBuilder(256);
12114 // Any package can hold static shared libraries.
12115 if (pkg.getStaticSharedLibName() != null) {
12116 if (removeSharedLibraryLPw(pkg.getStaticSharedLibName(),
12117 pkg.getStaticSharedLibVersion())) {
12118 if (DEBUG_REMOVE && chatty) {
12120 r = new StringBuilder(256);
12124 r.append(pkg.getStaticSharedLibName());
12130 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r);
12135 public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
12136 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
12137 final int[] userIds, int[] instantUserIds) {
12138 mHandler.post(() -> {
12140 final IActivityManager am = ActivityManager.getService();
12141 if (am == null) return;
12142 final int[] resolvedUserIds;
12143 if (userIds == null) {
12144 resolvedUserIds = am.getRunningUserIds();
12146 resolvedUserIds = userIds;
12148 doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
12149 resolvedUserIds, false);
12150 if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
12151 doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
12152 instantUserIds, true);
12154 } catch (RemoteException ex) {
12160 public void notifyPackageAdded(String packageName, int uid) {
12161 final PackageListObserver[] observers;
12162 synchronized (mLock) {
12163 if (mPackageListObservers.size() == 0) {
12166 final PackageListObserver[] observerArray =
12167 new PackageListObserver[mPackageListObservers.size()];
12168 observers = mPackageListObservers.toArray(observerArray);
12170 for (int i = observers.length - 1; i >= 0; --i) {
12171 observers[i].onPackageAdded(packageName, uid);
12176 public void notifyPackageChanged(String packageName, int uid) {
12177 final PackageListObserver[] observers;
12178 synchronized (mLock) {
12179 if (mPackageListObservers.size() == 0) {
12182 final PackageListObserver[] observerArray =
12183 new PackageListObserver[mPackageListObservers.size()];
12184 observers = mPackageListObservers.toArray(observerArray);
12186 for (int i = observers.length - 1; i >= 0; --i) {
12187 observers[i].onPackageChanged(packageName, uid);
12191 private static final Comparator<ProviderInfo> sProviderInitOrderSorter = (p1, p2) -> {
12192 final int v1 = p1.initOrder;
12193 final int v2 = p2.initOrder;
12194 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
12198 public void notifyPackageRemoved(String packageName, int uid) {
12199 final PackageListObserver[] observers;
12200 synchronized (mLock) {
12201 if (mPackageListObservers.size() == 0) {
12204 final PackageListObserver[] observerArray =
12205 new PackageListObserver[mPackageListObservers.size()];
12206 observers = mPackageListObservers.toArray(observerArray);
12208 for (int i = observers.length - 1; i >= 0; --i) {
12209 observers[i].onPackageRemoved(packageName, uid);
12214 * Sends a broadcast for the given action.
12215 * <p>If {@code isInstantApp} is {@code true}, then the broadcast is protected with
12216 * the {@link android.Manifest.permission#ACCESS_INSTANT_APPS} permission. This allows
12217 * the system and applications allowed to see instant applications to receive package
12218 * lifecycle events for instant applications.
12220 private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
12221 int flags, String targetPkg, IIntentReceiver finishedReceiver,
12222 int[] userIds, boolean isInstantApp)
12223 throws RemoteException {
12224 for (int id : userIds) {
12225 final Intent intent = new Intent(action,
12226 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
12227 final String[] requiredPermissions =
12228 isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null;
12229 if (extras != null) {
12230 intent.putExtras(extras);
12232 if (targetPkg != null) {
12233 intent.setPackage(targetPkg);
12235 // Modify the UID when posting to other users
12236 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
12237 if (uid > 0 && UserHandle.getUserId(uid) != id) {
12238 uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
12239 intent.putExtra(Intent.EXTRA_UID, uid);
12241 intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
12242 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
12243 if (DEBUG_BROADCASTS) {
12244 RuntimeException here = new RuntimeException("here");
12245 here.fillInStackTrace();
12246 Slog.d(TAG, "Sending to user " + id + ": "
12247 + intent.toShortString(false, true, false, false)
12248 + " " + intent.getExtras(), here);
12250 am.broadcastIntentWithFeature(null, null, intent, null, finishedReceiver,
12251 0, null, null, requiredPermissions, android.app.AppOpsManager.OP_NONE,
12252 null, finishedReceiver != null, false, id);
12257 * Check if the external storage media is available. This is true if there
12258 * is a mounted external storage medium or if the external storage is
12261 private boolean isExternalMediaAvailable() {
12262 return mMediaMounted || Environment.isExternalStorageEmulated();
12266 * Ensure that the install reason matches what we know about the package installer (e.g. whether
12267 * it is acting on behalf on an enterprise or the user).
12269 * Note that the ordering of the conditionals in this method is important. The checks we perform
12270 * are as follows, in this order:
12272 * 1) If the install is being performed by a system app, we can trust the app to have set the
12273 * install reason correctly. Thus, we pass through the install reason unchanged, no matter
12275 * 2) If the install is being performed by a device or profile owner app, the install reason
12276 * should be enterprise policy. However, we cannot be sure that the device or profile owner
12277 * set the install reason correctly. If the app targets an older SDK version where install
12278 * reasons did not exist yet, or if the app author simply forgot, the install reason may be
12279 * unset or wrong. Thus, we force the install reason to be enterprise policy.
12280 * 3) In all other cases, the install is being performed by a regular app that is neither part
12281 * of the system nor a device or profile owner. We have no reason to believe that this app is
12282 * acting on behalf of the enterprise admin. Thus, we check whether the install reason was
12283 * set to enterprise policy and if so, change it to unknown instead.
12285 private int fixUpInstallReason(String installerPackageName, int installerUid,
12286 int installReason) {
12287 if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
12288 == PERMISSION_GRANTED) {
12289 // If the install is being performed by a system app, we trust that app to have set the
12290 // install reason correctly.
12291 return installReason;
12293 final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(
12294 UserHandle.getUserId(installerUid));
12295 if (ownerPackage != null && ownerPackage.equals(installerPackageName)) {
12296 // If the install is being performed by a device or profile owner, the install
12297 // reason should be enterprise policy.
12298 return PackageManager.INSTALL_REASON_POLICY;
12302 if (installReason == PackageManager.INSTALL_REASON_POLICY) {
12303 // If the install is being performed by a regular app (i.e. neither system app nor
12304 // device or profile owner), we have no reason to believe that the app is acting on
12305 // behalf of an enterprise. If the app set the install reason to enterprise policy,
12306 // change it to unknown instead.
12307 return PackageManager.INSTALL_REASON_UNKNOWN;
12310 // If the install is being performed by a regular app and the install reason was set to any
12311 // value but enterprise policy, leave the install reason unchanged.
12312 return installReason;
12315 void installStage(ActiveInstallSession activeInstallSession) {
12316 if (DEBUG_INSTANT) {
12317 if ((activeInstallSession.getSessionParams().installFlags
12318 & PackageManager.INSTALL_INSTANT_APP) != 0) {
12319 Slog.d(TAG, "Ephemeral install of " + activeInstallSession.getPackageName());
12322 final Message msg = mHandler.obtainMessage(INIT_COPY);
12323 final InstallParams params = new InstallParams(activeInstallSession);
12324 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
12327 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
12328 System.identityHashCode(msg.obj));
12329 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
12330 System.identityHashCode(msg.obj));
12332 mHandler.sendMessage(msg);
12335 void installStage(List<ActiveInstallSession> children)
12336 throws PackageManagerException {
12337 final Message msg = mHandler.obtainMessage(INIT_COPY);
12338 final MultiPackageInstallParams params =
12339 new MultiPackageInstallParams(UserHandle.ALL, children);
12340 params.setTraceMethod("installStageMultiPackage")
12341 .setTraceCookie(System.identityHashCode(params));
12344 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStageMultiPackage",
12345 System.identityHashCode(msg.obj));
12346 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
12347 System.identityHashCode(msg.obj));
12348 mHandler.sendMessage(msg);
12351 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
12353 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
12354 final boolean isInstantApp = pkgSetting.getInstantApp(userId);
12355 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
12356 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
12357 sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
12358 false /*startReceiver*/, pkgSetting.appId, userIds, instantUserIds);
12360 // Send a session commit broadcast
12361 final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
12362 info.installReason = pkgSetting.getInstallReason(userId);
12363 info.appPackageName = packageName;
12364 sendSessionCommitBroadcast(info, userId);
12368 public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
12369 boolean includeStopped, @AppIdInt int appId, int[] userIds, int[] instantUserIds) {
12370 if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
12373 Bundle extras = new Bundle(1);
12374 // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
12375 final int uid = UserHandle.getUid(
12376 (ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId);
12377 extras.putInt(Intent.EXTRA_UID, uid);
12379 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
12380 packageName, extras, 0, null, null, userIds, instantUserIds);
12381 if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
12382 mHandler.post(() -> {
12383 for (int userId : userIds) {
12384 sendBootCompletedBroadcastToSystemApp(
12385 packageName, includeStopped, userId);
12393 * The just-installed/enabled app is bundled on the system, so presumed to be able to run
12394 * automatically without needing an explicit launch.
12395 * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
12397 private void sendBootCompletedBroadcastToSystemApp(
12398 String packageName, boolean includeStopped, int userId) {
12399 // If user is not running, the app didn't miss any broadcast
12400 if (!mUserManager.isUserRunning(userId)) {
12403 final IActivityManager am = ActivityManager.getService();
12405 // Deliver LOCKED_BOOT_COMPLETED first
12406 Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
12407 .setPackage(packageName);
12408 if (includeStopped) {
12409 lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
12411 final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
12412 am.broadcastIntentWithFeature(null, null, lockedBcIntent, null, null, 0, null, null,
12413 requiredPermissions, android.app.AppOpsManager.OP_NONE, null, false, false,
12416 // Deliver BOOT_COMPLETED only if user is unlocked
12417 if (mUserManager.isUserUnlockingOrUnlocked(userId)) {
12418 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
12419 if (includeStopped) {
12420 bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
12422 am.broadcastIntentWithFeature(null, null, bcIntent, null, null, 0, null, null,
12423 requiredPermissions, android.app.AppOpsManager.OP_NONE, null, false, false,
12426 } catch (RemoteException e) {
12427 throw e.rethrowFromSystemServer();
12432 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
12434 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
12435 PackageSetting pkgSetting;
12436 final int callingUid = Binder.getCallingUid();
12437 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
12438 true /* requireFullPermission */, true /* checkShell */,
12439 "setApplicationHiddenSetting for user " + userId);
12441 if (hidden && isPackageDeviceAdmin(packageName, userId)) {
12442 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
12446 long callingId = Binder.clearCallingIdentity();
12448 boolean sendAdded = false;
12449 boolean sendRemoved = false;
12451 synchronized (mLock) {
12452 pkgSetting = mSettings.mPackages.get(packageName);
12453 if (pkgSetting == null) {
12456 if (shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
12459 // Do not allow "android" is being disabled
12460 if ("android".equals(packageName)) {
12461 Slog.w(TAG, "Cannot hide package: android");
12464 // Cannot hide static shared libs as they are considered
12465 // a part of the using app (emulating static linking). Also
12466 // static libs are installed always on internal storage.
12467 AndroidPackage pkg = mPackages.get(packageName);
12468 if (pkg != null && pkg.getStaticSharedLibName() != null) {
12469 Slog.w(TAG, "Cannot hide package: " + packageName
12470 + " providing static shared library: "
12471 + pkg.getStaticSharedLibName());
12474 // Only allow protected packages to hide themselves.
12475 if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
12476 && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
12477 Slog.w(TAG, "Not hiding protected package: " + packageName);
12481 if (pkgSetting.getHidden(userId) != hidden) {
12482 pkgSetting.setHidden(hidden, userId);
12483 mSettings.writePackageRestrictionsLPr(userId);
12485 sendRemoved = true;
12492 sendPackageAddedForUser(packageName, pkgSetting, userId);
12496 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
12498 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
12502 Binder.restoreCallingIdentity(callingId);
12508 public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) {
12509 final int callingUid = Binder.getCallingUid();
12510 PackageManagerServiceUtils
12511 .enforceSystemOrPhoneCaller("setSystemAppHiddenUntilInstalled", callingUid);
12512 synchronized (mLock) {
12513 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
12514 if (pkgSetting == null || !pkgSetting.isSystem()) {
12517 pkgSetting.getPkgState().setHiddenUntilInstalled(hidden);
12518 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(packageName);
12519 if (disabledPs == null) {
12522 disabledPs.getPkgState().setHiddenUntilInstalled(hidden);
12527 public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
12528 final int callingUid = Binder.getCallingUid();
12529 PackageManagerServiceUtils
12530 .enforceSystemOrPhoneCaller("setSystemAppInstallState", callingUid);
12531 synchronized (mLock) {
12532 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
12533 // The target app should always be in system
12534 if (pkgSetting == null || !pkgSetting.isSystem()) {
12537 // Check if the install state is the same
12538 if (pkgSetting.getInstalled(userId) == installed) {
12543 final long callingId = Binder.clearCallingIdentity();
12546 // install the app from uninstalled state
12547 installExistingPackageAsUser(
12550 PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
12551 PackageManager.INSTALL_REASON_DEVICE_SETUP,
12556 // uninstall the app from installed state
12557 deletePackageVersioned(
12558 new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
12559 new LegacyPackageDeleteObserver(null).getBinder(),
12561 PackageManager.DELETE_SYSTEM_APP);
12564 Binder.restoreCallingIdentity(callingId);
12568 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
12570 final PackageRemovedInfo info = new PackageRemovedInfo(this);
12571 info.removedPackage = packageName;
12572 info.installerPackageName = pkgSetting.installSource.installerPackageName;
12573 info.removedUsers = new int[] {userId};
12574 info.broadcastUsers = new int[] {userId};
12575 info.uid = UserHandle.getUid(userId, pkgSetting.appId);
12576 info.sendPackageRemovedBroadcasts(true /*killApp*/);
12579 private void sendDistractingPackagesChanged(String[] pkgList, int[] uidList, int userId,
12580 int distractionFlags) {
12581 final Bundle extras = new Bundle(3);
12582 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
12583 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
12584 extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags);
12585 sendPackageBroadcast(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null, extras,
12586 Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, new int[]{userId}, null);
12589 private void sendPackagesSuspendedForUser(String[] pkgList, int[] uidList, int userId,
12590 boolean suspended) {
12591 final Bundle extras = new Bundle(3);
12592 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
12593 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
12594 sendPackageBroadcast(
12595 suspended ? Intent.ACTION_PACKAGES_SUSPENDED
12596 : Intent.ACTION_PACKAGES_UNSUSPENDED,
12597 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
12598 new int[] {userId}, null);
12602 * Returns true if application is not found or there was an error. Otherwise it returns
12603 * the hidden state of the package for the given user.
12606 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
12607 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
12608 final int callingUid = Binder.getCallingUid();
12609 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
12610 true /* requireFullPermission */, false /* checkShell */,
12611 "getApplicationHidden for user " + userId);
12613 long callingId = Binder.clearCallingIdentity();
12616 synchronized (mLock) {
12617 ps = mSettings.mPackages.get(packageName);
12621 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
12624 return ps.getHidden(userId);
12627 Binder.restoreCallingIdentity(callingId);
12635 public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
12636 int installReason, List<String> whiteListedPermissions) {
12637 return installExistingPackageAsUser(packageName, userId, installFlags, installReason,
12638 whiteListedPermissions, null);
12641 int installExistingPackageAsUser(@Nullable String packageName, @UserIdInt int userId,
12642 @PackageManager.InstallFlags int installFlags,
12643 @PackageManager.InstallReason int installReason,
12644 @Nullable List<String> whiteListedPermissions, @Nullable IntentSender intentSender) {
12645 if (DEBUG_INSTALL) {
12646 Log.v(TAG, "installExistingPackageAsUser package=" + packageName + " userId=" + userId
12647 + " installFlags=" + installFlags + " installReason=" + installReason
12648 + " whiteListedPermissions=" + whiteListedPermissions);
12651 final int callingUid = Binder.getCallingUid();
12652 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES)
12653 != PackageManager.PERMISSION_GRANTED
12654 && mContext.checkCallingOrSelfPermission(
12655 android.Manifest.permission.INSTALL_EXISTING_PACKAGES)
12656 != PackageManager.PERMISSION_GRANTED) {
12657 throw new SecurityException("Neither user " + callingUid + " nor current process has "
12658 + android.Manifest.permission.INSTALL_PACKAGES + ".");
12660 PackageSetting pkgSetting;
12661 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
12662 true /* requireFullPermission */, true /* checkShell */,
12663 "installExistingPackage for user " + userId);
12664 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
12665 return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
12668 long callingId = Binder.clearCallingIdentity();
12670 boolean installed = false;
12671 final boolean instantApp =
12672 (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
12673 final boolean fullApp =
12674 (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
12677 synchronized (mLock) {
12678 pkgSetting = mSettings.mPackages.get(packageName);
12679 if (pkgSetting == null) {
12680 return PackageManager.INSTALL_FAILED_INVALID_URI;
12682 if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
12683 // only allow the existing package to be used if it's installed as a full
12684 // application for at least one user
12685 boolean installAllowed = false;
12686 for (int checkUserId : mUserManager.getUserIds()) {
12687 installAllowed = !pkgSetting.getInstantApp(checkUserId);
12688 if (installAllowed) {
12692 if (!installAllowed) {
12693 return PackageManager.INSTALL_FAILED_INVALID_URI;
12696 if (!pkgSetting.getInstalled(userId)) {
12697 pkgSetting.setInstalled(true, userId);
12698 pkgSetting.setHidden(false, userId);
12699 pkgSetting.setInstallReason(installReason, userId);
12700 mSettings.writePackageRestrictionsLPr(userId);
12701 mSettings.writeKernelMappingLPr(pkgSetting);
12703 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
12704 // upgrade app from instant to full; we don't allow app downgrade
12707 setInstantAppForUser(mInjector, pkgSetting, userId, instantApp, fullApp);
12711 if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS)
12712 != 0 && pkgSetting.pkg != null) {
12713 whiteListedPermissions = pkgSetting.pkg.getRequestedPermissions();
12715 mPermissionManager.setWhitelistedRestrictedPermissions(packageName,
12716 whiteListedPermissions, FLAG_PERMISSION_WHITELIST_INSTALLER, userId);
12718 if (pkgSetting.pkg != null) {
12719 synchronized (mInstallLock) {
12720 // We don't need to freeze for a brand new install
12721 prepareAppDataAfterInstallLIF(pkgSetting.pkg);
12724 sendPackageAddedForUser(packageName, pkgSetting, userId);
12725 synchronized (mLock) {
12726 updateSequenceNumberLP(pkgSetting, new int[]{ userId });
12728 // start async restore with no post-install since we finish install here
12729 PackageInstalledInfo res =
12730 createPackageInstalledInfo(PackageManager.INSTALL_SUCCEEDED);
12731 res.pkg = pkgSetting.pkg;
12732 res.newUsers = new int[]{ userId };
12733 PostInstallData postInstallData = intentSender == null ? null :
12734 new PostInstallData(null, res, () -> onRestoreComplete(res.returnCode,
12735 mContext, intentSender));
12736 restoreAndPostInstall(userId, res, postInstallData);
12739 Binder.restoreCallingIdentity(callingId);
12742 return PackageManager.INSTALL_SUCCEEDED;
12745 static void onRestoreComplete(int returnCode, Context context, IntentSender target) {
12746 Intent fillIn = new Intent();
12747 fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
12748 PackageManager.installStatusToPublicStatus(returnCode));
12750 target.sendIntent(context, 0, fillIn, null, null);
12751 } catch (SendIntentException ignored) {
12755 static void setInstantAppForUser(Injector injector, PackageSetting pkgSetting,
12756 int userId, boolean instantApp, boolean fullApp) {
12757 // no state specified; do nothing
12758 if (!instantApp && !fullApp) {
12761 if (userId != UserHandle.USER_ALL) {
12762 if (instantApp && !pkgSetting.getInstantApp(userId)) {
12763 pkgSetting.setInstantApp(true /*instantApp*/, userId);
12764 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
12765 pkgSetting.setInstantApp(false /*instantApp*/, userId);
12768 for (int currentUserId : injector.getUserManagerInternal().getUserIds()) {
12769 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
12770 pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
12771 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
12772 pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
12778 boolean isUserRestricted(int userId, String restrictionKey) {
12779 Bundle restrictions = mUserManager.getUserRestrictions(userId);
12780 if (restrictions.getBoolean(restrictionKey, false)) {
12781 Log.w(TAG, "User is restricted: " + restrictionKey);
12788 public String[] setDistractingPackageRestrictionsAsUser(String[] packageNames,
12789 int restrictionFlags, int userId) {
12790 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
12791 "setDistractingPackageRestrictionsAsUser");
12793 final int callingUid = Binder.getCallingUid();
12794 if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID
12795 && UserHandle.getUserId(callingUid) != userId) {
12796 throw new SecurityException("Calling uid " + callingUid + " cannot call for user "
12799 Objects.requireNonNull(packageNames, "packageNames cannot be null");
12800 if (restrictionFlags != 0 && !isSuspendAllowedForUser(userId)) {
12801 Slog.w(TAG, "Cannot restrict packages due to restrictions on user " + userId);
12802 return packageNames;
12805 final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
12806 final IntArray changedUids = new IntArray(packageNames.length);
12807 final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
12808 final boolean[] canRestrict = (restrictionFlags != 0) ? canSuspendPackageForUserInternal(
12809 packageNames, userId) : null;
12811 for (int i = 0; i < packageNames.length; i++) {
12812 final String packageName = packageNames[i];
12813 final PackageSetting pkgSetting;
12814 synchronized (mLock) {
12815 pkgSetting = mSettings.mPackages.get(packageName);
12816 if (pkgSetting == null
12817 || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
12818 Slog.w(TAG, "Could not find package setting for package: " + packageName
12819 + ". Skipping...");
12820 unactionedPackages.add(packageName);
12824 if (canRestrict != null && !canRestrict[i]) {
12825 unactionedPackages.add(packageName);
12828 synchronized (mLock) {
12829 final int oldDistractionFlags = pkgSetting.getDistractionFlags(userId);
12830 if (restrictionFlags != oldDistractionFlags) {
12831 pkgSetting.setDistractionFlags(restrictionFlags, userId);
12832 changedPackagesList.add(packageName);
12833 changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
12838 if (!changedPackagesList.isEmpty()) {
12839 final String[] changedPackages = changedPackagesList.toArray(
12840 new String[changedPackagesList.size()]);
12841 sendDistractingPackagesChanged(changedPackages, changedUids.toArray(), userId,
12843 synchronized (mLock) {
12844 scheduleWritePackageRestrictionsLocked(userId);
12847 return unactionedPackages.toArray(new String[0]);
12850 private void enforceCanSetPackagesSuspendedAsUser(String callingPackage, int callingUid,
12851 int userId, String callingMethod) {
12852 if (callingUid == Process.ROOT_UID || callingUid == Process.SYSTEM_UID) {
12856 final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
12857 if (ownerPackage != null) {
12858 final int ownerUid = getPackageUid(ownerPackage, 0, userId);
12859 if (ownerUid == callingUid) {
12864 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
12867 final int packageUid = getPackageUid(callingPackage, 0, userId);
12868 final boolean allowedPackageUid = packageUid == callingUid;
12869 // TODO(b/139383163): remove special casing for shell and enforce INTERACT_ACROSS_USERS_FULL
12870 final boolean allowedShell = callingUid == SHELL_UID
12871 && UserHandle.isSameApp(packageUid, callingUid);
12873 if (!allowedShell && !allowedPackageUid) {
12874 throw new SecurityException("Calling package " + callingPackage + " in user "
12875 + userId + " does not belong to calling uid " + callingUid);
12880 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
12881 PersistableBundle appExtras, PersistableBundle launcherExtras,
12882 SuspendDialogInfo dialogInfo, String callingPackage, int userId) {
12883 final int callingUid = Binder.getCallingUid();
12884 enforceCanSetPackagesSuspendedAsUser(callingPackage, callingUid, userId,
12885 "setPackagesSuspendedAsUser");
12887 if (ArrayUtils.isEmpty(packageNames)) {
12888 return packageNames;
12890 if (suspended && !isSuspendAllowedForUser(userId)) {
12891 Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId);
12892 return packageNames;
12895 final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
12896 final IntArray changedUids = new IntArray(packageNames.length);
12897 final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
12898 final boolean[] canSuspend = suspended ? canSuspendPackageForUserInternal(packageNames,
12901 for (int i = 0; i < packageNames.length; i++) {
12902 final String packageName = packageNames[i];
12903 if (callingPackage.equals(packageName)) {
12904 Slog.w(TAG, "Calling package: " + callingPackage + " trying to "
12905 + (suspended ? "" : "un") + "suspend itself. Ignoring");
12906 unactionedPackages.add(packageName);
12909 final PackageSetting pkgSetting;
12910 synchronized (mLock) {
12911 pkgSetting = mSettings.mPackages.get(packageName);
12912 if (pkgSetting == null
12913 || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
12914 Slog.w(TAG, "Could not find package setting for package: " + packageName
12915 + ". Skipping suspending/un-suspending.");
12916 unactionedPackages.add(packageName);
12920 if (canSuspend != null && !canSuspend[i]) {
12921 unactionedPackages.add(packageName);
12924 boolean packageUnsuspended;
12925 synchronized (mLock) {
12927 pkgSetting.addOrUpdateSuspension(callingPackage, dialogInfo, appExtras,
12928 launcherExtras, userId);
12930 pkgSetting.removeSuspension(callingPackage, userId);
12932 packageUnsuspended = !suspended && !pkgSetting.getSuspended(userId);
12934 if (suspended || packageUnsuspended) {
12935 changedPackagesList.add(packageName);
12936 changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
12940 if (!changedPackagesList.isEmpty()) {
12941 final String[] changedPackages = changedPackagesList.toArray(
12942 new String[changedPackagesList.size()]);
12943 sendPackagesSuspendedForUser(changedPackages, changedUids.toArray(), userId, suspended);
12944 sendMyPackageSuspendedOrUnsuspended(changedPackages, suspended, userId);
12945 synchronized (mLock) {
12946 scheduleWritePackageRestrictionsLocked(userId);
12949 return unactionedPackages.toArray(new String[unactionedPackages.size()]);
12953 public Bundle getSuspendedPackageAppExtras(String packageName, int userId) {
12954 final int callingUid = Binder.getCallingUid();
12955 if (getPackageUid(packageName, 0, userId) != callingUid) {
12956 throw new SecurityException("Calling package " + packageName
12957 + " does not belong to calling uid " + callingUid);
12959 return getSuspendedPackageAppExtrasInternal(packageName, userId);
12962 private Bundle getSuspendedPackageAppExtrasInternal(String packageName, int userId) {
12963 synchronized (mLock) {
12964 final PackageSetting ps = mSettings.mPackages.get(packageName);
12966 throw new IllegalArgumentException("Unknown target package: " + packageName);
12968 final PackageUserState pus = ps.readUserState(userId);
12969 final Bundle allExtras = new Bundle();
12970 if (pus.suspended) {
12971 for (int i = 0; i < pus.suspendParams.size(); i++) {
12972 final PackageUserState.SuspendParams params = pus.suspendParams.valueAt(i);
12973 if (params != null && params.appExtras != null) {
12974 allExtras.putAll(params.appExtras);
12978 return (allExtras.size() > 0) ? allExtras : null;
12982 private void sendMyPackageSuspendedOrUnsuspended(String[] affectedPackages, boolean suspended,
12984 final String action = suspended
12985 ? Intent.ACTION_MY_PACKAGE_SUSPENDED
12986 : Intent.ACTION_MY_PACKAGE_UNSUSPENDED;
12987 mHandler.post(() -> {
12989 final IActivityManager am = ActivityManager.getService();
12991 Slog.wtf(TAG, "IActivityManager null. Cannot send MY_PACKAGE_ "
12992 + (suspended ? "" : "UN") + "SUSPENDED broadcasts");
12995 final int[] targetUserIds = new int[] {userId};
12996 for (String packageName : affectedPackages) {
12997 final Bundle appExtras = suspended
12998 ? getSuspendedPackageAppExtrasInternal(packageName, userId)
13000 final Bundle intentExtras;
13001 if (appExtras != null) {
13002 intentExtras = new Bundle(1);
13003 intentExtras.putBundle(Intent.EXTRA_SUSPENDED_PACKAGE_EXTRAS, appExtras);
13005 intentExtras = null;
13007 doSendBroadcast(am, action, null, intentExtras,
13008 Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, packageName, null,
13009 targetUserIds, false);
13011 } catch (RemoteException ex) {
13012 // Shouldn't happen as AMS is in the same process.
13018 public boolean isPackageSuspendedForUser(String packageName, int userId) {
13019 final int callingUid = Binder.getCallingUid();
13020 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13021 true /* requireFullPermission */, false /* checkShell */,
13022 "isPackageSuspendedForUser for user " + userId);
13023 synchronized (mLock) {
13024 final PackageSetting ps = mSettings.mPackages.get(packageName);
13025 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
13026 throw new IllegalArgumentException("Unknown target package: " + packageName);
13028 return ps.getSuspended(userId);
13032 void unsuspendForSuspendingPackage(String suspendingPackage, int userId) {
13033 final String[] allPackages;
13034 synchronized (mLock) {
13035 allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
13037 removeSuspensionsBySuspendingPackage(allPackages, suspendingPackage::equals, userId);
13041 * Removes any suspensions on given packages that were added by packages that pass the given
13044 * <p> Caller must flush package restrictions if it cares about immediate data consistency.
13046 * @param packagesToChange The packages on which the suspension are to be removed.
13047 * @param suspendingPackagePredicate A predicate identifying the suspending packages whose
13048 * suspensions will be removed.
13049 * @param userId The user for which the changes are taking place.
13051 void removeSuspensionsBySuspendingPackage(String[] packagesToChange,
13052 Predicate<String> suspendingPackagePredicate, int userId) {
13053 final List<String> unsuspendedPackages = new ArrayList<>();
13054 final IntArray unsuspendedUids = new IntArray();
13055 synchronized (mLock) {
13056 for (String packageName : packagesToChange) {
13057 final PackageSetting ps = mSettings.mPackages.get(packageName);
13058 if (ps.getSuspended(userId)) {
13059 ps.removeSuspension(suspendingPackagePredicate, userId);
13060 if (!ps.getSuspended(userId)) {
13061 unsuspendedPackages.add(ps.name);
13062 unsuspendedUids.add(UserHandle.getUid(userId, ps.getAppId()));
13066 scheduleWritePackageRestrictionsLocked(userId);
13068 if (!unsuspendedPackages.isEmpty()) {
13069 final String[] packageArray = unsuspendedPackages.toArray(
13070 new String[unsuspendedPackages.size()]);
13071 sendMyPackageSuspendedOrUnsuspended(packageArray, false, userId);
13072 sendPackagesSuspendedForUser(packageArray, unsuspendedUids.toArray(), userId, false);
13076 void removeAllDistractingPackageRestrictions(int userId) {
13077 final String[] allPackages;
13078 synchronized (mLock) {
13079 allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
13081 PackageManagerService.this.removeDistractingPackageRestrictions(allPackages, userId);
13085 * Removes any {@link android.content.pm.PackageManager.DistractionRestriction restrictions}
13086 * set on given packages.
13088 * <p> Caller must flush package restrictions if it cares about immediate data consistency.
13090 * @param packagesToChange The packages on which restrictions are to be removed.
13091 * @param userId the user for which changes are taking place.
13093 void removeDistractingPackageRestrictions(String[] packagesToChange, int userId) {
13094 final List<String> changedPackages = new ArrayList<>();
13095 final IntArray changedUids = new IntArray();
13096 synchronized (mLock) {
13097 for (String packageName : packagesToChange) {
13098 final PackageSetting ps = mSettings.mPackages.get(packageName);
13099 if (ps.getDistractionFlags(userId) != 0) {
13100 ps.setDistractionFlags(0, userId);
13101 changedPackages.add(ps.name);
13102 changedUids.add(UserHandle.getUid(userId, ps.getAppId()));
13105 if (!changedPackages.isEmpty()) {
13106 final String[] packageArray = changedPackages.toArray(
13107 new String[changedPackages.size()]);
13108 sendDistractingPackagesChanged(packageArray, changedUids.toArray(), userId, 0);
13109 scheduleWritePackageRestrictionsLocked(userId);
13114 private boolean isCallerDeviceOrProfileOwner(int userId) {
13115 final int callingUid = Binder.getCallingUid();
13116 if (callingUid == Process.SYSTEM_UID) {
13119 final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
13120 if (ownerPackage != null) {
13121 return callingUid == getPackageUidInternal(ownerPackage, 0, userId, callingUid);
13126 private boolean isSuspendAllowedForUser(int userId) {
13127 return isCallerDeviceOrProfileOwner(userId)
13128 || (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL, userId)
13129 && !mUserManager.hasUserRestriction(UserManager.DISALLOW_UNINSTALL_APPS, userId));
13133 public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) {
13134 Objects.requireNonNull(packageNames, "packageNames cannot be null");
13135 mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
13136 "getUnsuspendablePackagesForUser");
13137 final int callingUid = Binder.getCallingUid();
13138 if (UserHandle.getUserId(callingUid) != userId) {
13139 throw new SecurityException("Calling uid " + callingUid
13140 + " cannot query getUnsuspendablePackagesForUser for user " + userId);
13142 if (!isSuspendAllowedForUser(userId)) {
13143 Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId);
13144 return packageNames;
13146 final ArraySet<String> unactionablePackages = new ArraySet<>();
13147 final boolean[] canSuspend = canSuspendPackageForUserInternal(packageNames, userId);
13148 for (int i = 0; i < packageNames.length; i++) {
13149 if (!canSuspend[i]) {
13150 unactionablePackages.add(packageNames[i]);
13153 synchronized (mLock) {
13154 final PackageSetting ps = mSettings.mPackages.get(packageNames[i]);
13155 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
13156 Slog.w(TAG, "Could not find package setting for package: " + packageNames[i]);
13157 unactionablePackages.add(packageNames[i]);
13161 return unactionablePackages.toArray(new String[unactionablePackages.size()]);
13165 * Returns an array of booleans, such that the ith boolean denotes whether the ith package can
13166 * be suspended or not.
13168 * @param packageNames The package names to check suspendability for.
13169 * @param userId The user to check in
13170 * @return An array containing results of the checks
13173 private boolean[] canSuspendPackageForUserInternal(@NonNull String[] packageNames, int userId) {
13174 final boolean[] canSuspend = new boolean[packageNames.length];
13175 final boolean isCallerOwner = isCallerDeviceOrProfileOwner(userId);
13176 final long callingId = Binder.clearCallingIdentity();
13178 final String activeLauncherPackageName = getActiveLauncherPackageName(userId);
13179 final String dialerPackageName = mPermissionManager.getDefaultDialer(userId);
13180 for (int i = 0; i < packageNames.length; i++) {
13181 canSuspend[i] = false;
13182 final String packageName = packageNames[i];
13184 if (isPackageDeviceAdmin(packageName, userId)) {
13185 Slog.w(TAG, "Cannot suspend package \"" + packageName
13186 + "\": has an active device admin");
13189 if (packageName.equals(activeLauncherPackageName)) {
13190 Slog.w(TAG, "Cannot suspend package \"" + packageName
13191 + "\": contains the active launcher");
13194 if (packageName.equals(mRequiredInstallerPackage)) {
13195 Slog.w(TAG, "Cannot suspend package \"" + packageName
13196 + "\": required for package installation");
13199 if (packageName.equals(mRequiredUninstallerPackage)) {
13200 Slog.w(TAG, "Cannot suspend package \"" + packageName
13201 + "\": required for package uninstallation");
13204 if (packageName.equals(mRequiredVerifierPackage)) {
13205 Slog.w(TAG, "Cannot suspend package \"" + packageName
13206 + "\": required for package verification");
13209 if (packageName.equals(dialerPackageName)) {
13210 Slog.w(TAG, "Cannot suspend package \"" + packageName
13211 + "\": is the default dialer");
13214 if (packageName.equals(mRequiredPermissionControllerPackage)) {
13215 Slog.w(TAG, "Cannot suspend package \"" + packageName
13216 + "\": required for permissions management");
13219 synchronized (mLock) {
13220 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13221 Slog.w(TAG, "Cannot suspend package \"" + packageName
13222 + "\": protected package");
13225 if (!isCallerOwner && mSettings.getBlockUninstallLPr(userId, packageName)) {
13226 Slog.w(TAG, "Cannot suspend package \"" + packageName
13227 + "\": blocked by admin");
13231 // Cannot suspend static shared libs as they are considered
13232 // a part of the using app (emulating static linking). Also
13233 // static libs are installed always on internal storage.
13234 AndroidPackage pkg = mPackages.get(packageName);
13235 if (pkg != null && pkg.isStaticSharedLibrary()) {
13236 Slog.w(TAG, "Cannot suspend package: " + packageName
13237 + " providing static shared library: "
13238 + pkg.getStaticSharedLibName());
13242 if (PLATFORM_PACKAGE_NAME.equals(packageName)) {
13243 Slog.w(TAG, "Cannot suspend the platform package: " + packageName);
13246 canSuspend[i] = true;
13249 Binder.restoreCallingIdentity(callingId);
13254 private String getActiveLauncherPackageName(int userId) {
13255 Intent intent = new Intent(Intent.ACTION_MAIN);
13256 intent.addCategory(Intent.CATEGORY_HOME);
13257 ResolveInfo resolveInfo = resolveIntent(
13259 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
13260 PackageManager.MATCH_DEFAULT_ONLY,
13263 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
13267 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
13268 mContext.enforceCallingOrSelfPermission(
13269 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13270 "Only package verification agents can verify applications");
13272 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13273 final PackageVerificationResponse response = new PackageVerificationResponse(
13274 verificationCode, Binder.getCallingUid());
13276 msg.obj = response;
13277 mHandler.sendMessage(msg);
13281 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
13282 long millisecondsToDelay) {
13283 mContext.enforceCallingOrSelfPermission(
13284 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13285 "Only package verification agents can extend verification timeouts");
13287 final PackageVerificationState state = mPendingVerification.get(id);
13288 final PackageVerificationResponse response = new PackageVerificationResponse(
13289 verificationCodeAtTimeout, Binder.getCallingUid());
13291 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
13292 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
13294 if (millisecondsToDelay < 0) {
13295 millisecondsToDelay = 0;
13297 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
13298 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
13299 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
13302 if ((state != null) && !state.timeoutExtended()) {
13303 state.extendTimeout();
13305 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13307 msg.obj = response;
13308 mHandler.sendMessageDelayed(msg, millisecondsToDelay);
13312 private void broadcastPackageVerified(int verificationId, Uri packageUri,
13313 int verificationCode, UserHandle user) {
13314 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
13315 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
13316 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
13317 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
13318 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
13320 mContext.sendBroadcastAsUser(intent, user,
13321 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
13324 private ComponentName matchComponentForVerifier(String packageName,
13325 List<ResolveInfo> receivers) {
13326 ActivityInfo targetReceiver = null;
13328 final int NR = receivers.size();
13329 for (int i = 0; i < NR; i++) {
13330 final ResolveInfo info = receivers.get(i);
13331 if (info.activityInfo == null) {
13335 if (packageName.equals(info.activityInfo.packageName)) {
13336 targetReceiver = info.activityInfo;
13341 if (targetReceiver == null) {
13345 return new ComponentName(targetReceiver.packageName, targetReceiver.name);
13348 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
13349 List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
13350 if (pkgInfo.verifiers.length == 0) {
13354 final int N = pkgInfo.verifiers.length;
13355 final List<ComponentName> sufficientVerifiers = new ArrayList<>(N + 1);
13356 for (int i = 0; i < N; i++) {
13357 final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
13359 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
13361 if (comp == null) {
13365 final int verifierUid = getUidForVerifier(verifierInfo);
13366 if (verifierUid == -1) {
13370 if (DEBUG_VERIFY) {
13371 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
13372 + " with the correct signature");
13374 sufficientVerifiers.add(comp);
13375 verificationState.addSufficientVerifier(verifierUid);
13378 return sufficientVerifiers;
13381 private int getUidForVerifier(VerifierInfo verifierInfo) {
13382 synchronized (mLock) {
13383 final AndroidPackage pkg = mPackages.get(verifierInfo.packageName);
13386 } else if (pkg.getSigningDetails().signatures.length != 1) {
13387 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13388 + " has more than one signature; ignoring");
13393 * If the public key of the package's signature does not match
13394 * our expected public key, then this is a different package and
13398 final byte[] expectedPublicKey;
13400 final Signature verifierSig = pkg.getSigningDetails().signatures[0];
13401 final PublicKey publicKey = verifierSig.getPublicKey();
13402 expectedPublicKey = publicKey.getEncoded();
13403 } catch (CertificateException e) {
13407 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
13409 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
13410 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13411 + " does not have the expected public key; ignoring");
13415 return pkg.getUid();
13419 private void setEnableRollbackCode(int token, int enableRollbackCode) {
13420 final Message msg = mHandler.obtainMessage(ENABLE_ROLLBACK_STATUS);
13422 msg.arg2 = enableRollbackCode;
13423 mHandler.sendMessage(msg);
13427 public void finishPackageInstall(int token, boolean didLaunch) {
13428 enforceSystemOrRoot("Only the system is allowed to finish installs");
13430 if (DEBUG_INSTALL) {
13431 Slog.v(TAG, "BM finishing package install for " + token);
13433 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13435 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
13436 mHandler.sendMessage(msg);
13440 * Get the verification agent timeout. Used for both the APK verifier and the
13441 * intent filter verifier.
13443 * @return verification timeout in milliseconds
13445 private long getVerificationTimeout() {
13446 long timeout = Global.getLong(mContext.getContentResolver(),
13447 Global.PACKAGE_VERIFIER_TIMEOUT, DEFAULT_VERIFICATION_TIMEOUT);
13448 // The setting can be used to increase the timeout but not decrease it, since that is
13449 // equivalent to disabling the verifier.
13450 return Math.max(timeout, DEFAULT_VERIFICATION_TIMEOUT);
13454 * Get the default verification agent response code.
13456 * @return default verification response code
13458 private int getDefaultVerificationResponse(UserHandle user) {
13459 if (mUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
13460 return PackageManager.VERIFICATION_REJECT;
13462 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13463 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
13464 DEFAULT_VERIFICATION_RESPONSE);
13468 * Get the default integrity verification response code.
13470 private int getDefaultIntegrityVerificationResponse() {
13471 // We are not exposing this as a user-configurable setting because we don't want to provide
13472 // an easy way to get around the integrity check.
13473 return PackageManager.VERIFICATION_REJECT;
13477 * Check whether or not package verification has been enabled.
13479 * @return true if verification should be performed
13481 private boolean isVerificationEnabled(
13482 PackageInfoLite pkgInfoLite, int userId, int installFlags, int installerUid) {
13483 if (!DEFAULT_VERIFY_ENABLE) {
13487 // Check if installing from ADB
13488 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
13489 if (isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS)) {
13492 // Check if the developer wants to skip verification for ADB installs
13493 if ((installFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0) {
13494 synchronized (mLock) {
13495 if (mSettings.mPackages.get(pkgInfoLite.packageName) == null) {
13496 // Always verify fresh install
13500 // Only skip when apk is debuggable
13501 return !pkgInfoLite.debuggable;
13503 return Global.getInt(mContext.getContentResolver(),
13504 Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0;
13507 if ((installFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0) {
13511 // only when not installed from ADB, skip verification for instant apps when
13512 // the installer and verifier are the same.
13513 if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13514 if (mInstantAppInstallerActivity != null
13515 && mInstantAppInstallerActivity.packageName.equals(
13516 mRequiredVerifierPackage)) {
13518 mInjector.getAppOpsManager()
13519 .checkPackage(installerUid, mRequiredVerifierPackage);
13520 if (DEBUG_VERIFY) {
13521 Slog.i(TAG, "disable verification for instant app");
13524 } catch (SecurityException ignore) { }
13531 * Check whether or not integrity verification has been enabled.
13533 private boolean isIntegrityVerificationEnabled() {
13534 // We are not exposing this as a user-configurable setting because we don't want to provide
13535 // an easy way to get around the integrity check.
13536 return DEFAULT_INTEGRITY_VERIFY_ENABLE;
13540 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
13541 throws RemoteException {
13542 mContext.enforceCallingOrSelfPermission(
13543 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
13544 "Only intentfilter verification agents can verify applications");
13546 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
13547 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
13548 Binder.getCallingUid(), verificationCode, failedDomains);
13550 msg.obj = response;
13551 mHandler.sendMessage(msg);
13555 public int getIntentVerificationStatus(String packageName, int userId) {
13556 final int callingUid = Binder.getCallingUid();
13557 if (UserHandle.getUserId(callingUid) != userId) {
13558 mContext.enforceCallingOrSelfPermission(
13559 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13560 "getIntentVerificationStatus" + userId);
13562 if (getInstantAppPackageName(callingUid) != null) {
13563 return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
13565 synchronized (mLock) {
13566 final PackageSetting ps = mSettings.mPackages.get(packageName);
13568 || shouldFilterApplicationLocked(
13569 ps, callingUid, UserHandle.getUserId(callingUid))) {
13570 return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
13572 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
13577 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
13578 mContext.enforceCallingOrSelfPermission(
13579 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
13581 boolean result = false;
13582 synchronized (mLock) {
13583 final PackageSetting ps = mSettings.mPackages.get(packageName);
13584 if (shouldFilterApplicationLocked(
13585 ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
13588 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
13591 scheduleWritePackageRestrictionsLocked(userId);
13597 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
13598 String packageName) {
13599 final int callingUid = Binder.getCallingUid();
13600 if (getInstantAppPackageName(callingUid) != null) {
13601 return ParceledListSlice.emptyList();
13603 synchronized (mLock) {
13604 final PackageSetting ps = mSettings.mPackages.get(packageName);
13605 if (shouldFilterApplicationLocked(ps, callingUid, UserHandle.getUserId(callingUid))) {
13606 return ParceledListSlice.emptyList();
13608 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
13613 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
13614 if (TextUtils.isEmpty(packageName)) {
13615 return ParceledListSlice.emptyList();
13617 final int callingUid = Binder.getCallingUid();
13618 final int callingUserId = UserHandle.getUserId(callingUid);
13619 synchronized (mLock) {
13620 AndroidPackage pkg = mPackages.get(packageName);
13621 if (pkg == null || ArrayUtils.isEmpty(pkg.getActivities())) {
13622 return ParceledListSlice.emptyList();
13624 final PackageSetting ps = getPackageSetting(pkg.getPackageName());
13626 return ParceledListSlice.emptyList();
13628 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
13629 return ParceledListSlice.emptyList();
13631 final int count = ArrayUtils.size(pkg.getActivities());
13632 ArrayList<IntentFilter> result = new ArrayList<>();
13633 for (int n=0; n<count; n++) {
13634 ParsedActivity activity = pkg.getActivities().get(n);
13635 if (activity.getIntents() != null && activity.getIntents().size() > 0) {
13636 result.addAll(activity.getIntents());
13639 return new ParceledListSlice<IntentFilter>(result) {
13641 protected void writeElement(IntentFilter parcelable, Parcel dest, int callFlags) {
13642 // IntentFilter has final Parcelable methods, so redirect to the subclass
13643 ((ParsedIntentInfo) parcelable).writeIntentInfoToParcel(dest,
13651 * Get the "allow unknown sources" setting.
13653 * @return the current "allow unknown sources" setting
13655 private int getUnknownSourcesSettings() {
13656 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
13657 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
13662 public void setInstallerPackageName(String targetPackage, String installerPackageName) {
13663 final int callingUid = Binder.getCallingUid();
13664 if (getInstantAppPackageName(callingUid) != null) {
13668 synchronized (mLock) {
13669 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
13670 if (targetPackageSetting == null
13671 || shouldFilterApplicationLocked(
13672 targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
13673 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
13676 PackageSetting installerPackageSetting;
13677 if (installerPackageName != null) {
13678 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
13679 if (installerPackageSetting == null) {
13680 throw new IllegalArgumentException("Unknown installer package: "
13681 + installerPackageName);
13684 installerPackageSetting = null;
13687 Signature[] callerSignature;
13688 final int appId = UserHandle.getAppId(callingUid);
13689 final Object obj = mSettings.getSettingLPr(appId);
13691 if (obj instanceof SharedUserSetting) {
13693 ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
13694 } else if (obj instanceof PackageSetting) {
13695 callerSignature = ((PackageSetting)obj).signatures.mSigningDetails.signatures;
13697 throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
13700 throw new SecurityException("Unknown calling UID: " + callingUid);
13703 // Verify: can't set installerPackageName to a package that is
13704 // not signed with the same cert as the caller.
13705 if (installerPackageSetting != null) {
13706 if (compareSignatures(callerSignature,
13707 installerPackageSetting.signatures.mSigningDetails.signatures)
13708 != PackageManager.SIGNATURE_MATCH) {
13709 throw new SecurityException(
13710 "Caller does not have same cert as new installer package "
13711 + installerPackageName);
13715 // Verify: if target already has an installer package, it must
13716 // be signed with the same cert as the caller.
13717 String targetInstallerPackageName =
13718 targetPackageSetting.installSource.installerPackageName;
13719 if (targetInstallerPackageName != null) {
13720 PackageSetting setting = mSettings.mPackages.get(
13721 targetInstallerPackageName);
13722 // If the currently set package isn't valid, then it's always
13723 // okay to change it.
13724 if (setting != null) {
13725 if (compareSignatures(callerSignature,
13726 setting.signatures.mSigningDetails.signatures)
13727 != PackageManager.SIGNATURE_MATCH) {
13728 throw new SecurityException(
13729 "Caller does not have same cert as old installer package "
13730 + targetInstallerPackageName);
13736 targetPackageSetting.setInstallerPackageName(installerPackageName);
13737 mSettings.addInstallerPackageNames(targetPackageSetting.installSource);
13738 mAppsFilter.addPackage(targetPackageSetting, mSettings.mPackages);
13739 scheduleWriteSettingsLocked();
13744 public void setApplicationCategoryHint(String packageName, int categoryHint,
13745 String callerPackageName) {
13746 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
13747 throw new SecurityException("Instant applications don't have access to this method");
13749 mInjector.getAppOpsManager().checkPackage(Binder.getCallingUid(),
13750 callerPackageName);
13751 synchronized (mLock) {
13752 PackageSetting ps = mSettings.mPackages.get(packageName);
13754 throw new IllegalArgumentException("Unknown target package " + packageName);
13756 if (shouldFilterApplicationLocked(
13757 ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
13758 throw new IllegalArgumentException("Unknown target package " + packageName);
13760 if (!Objects.equals(callerPackageName, ps.installSource.installerPackageName)) {
13761 throw new IllegalArgumentException("Calling package " + callerPackageName
13762 + " is not installer for " + packageName);
13765 if (ps.categoryHint != categoryHint) {
13766 ps.categoryHint = categoryHint;
13767 scheduleWriteSettingsLocked();
13772 private void processPendingInstall(final InstallArgs args, final int currentStatus) {
13773 if (args.mMultiPackageInstallParams != null) {
13774 args.mMultiPackageInstallParams.tryProcessInstallRequest(args, currentStatus);
13776 PackageInstalledInfo res = createPackageInstalledInfo(currentStatus);
13777 processInstallRequestsAsync(
13778 res.returnCode == PackageManager.INSTALL_SUCCEEDED,
13779 Collections.singletonList(new InstallRequest(args, res)));
13783 // Queue up an async operation since the package installation may take a little while.
13784 private void processInstallRequestsAsync(boolean success,
13785 List<InstallRequest> installRequests) {
13786 mHandler.post(() -> {
13788 for (InstallRequest request : installRequests) {
13789 request.args.doPreInstall(request.installResult.returnCode);
13791 synchronized (mInstallLock) {
13792 installPackagesTracedLI(installRequests);
13794 for (InstallRequest request : installRequests) {
13795 request.args.doPostInstall(
13796 request.installResult.returnCode, request.installResult.uid);
13799 for (InstallRequest request : installRequests) {
13800 restoreAndPostInstall(request.args.user.getIdentifier(), request.installResult,
13801 new PostInstallData(request.args, request.installResult, null));
13806 private PackageInstalledInfo createPackageInstalledInfo(
13807 int currentStatus) {
13808 PackageInstalledInfo res = new PackageInstalledInfo();
13809 res.setReturnCode(currentStatus);
13812 res.removedInfo = null;
13816 /** @param data Post-install is performed only if this is non-null. */
13817 private void restoreAndPostInstall(
13818 int userId, PackageInstalledInfo res, @Nullable PostInstallData data) {
13819 if (DEBUG_INSTALL) {
13820 Log.v(TAG, "restoreAndPostInstall userId=" + userId + " package=" + res.pkg);
13823 // A restore should be performed at this point if (a) the install
13824 // succeeded, (b) the operation is not an update, and (c) the new
13825 // package has not opted out of backup participation.
13826 final boolean update = res.removedInfo != null
13827 && res.removedInfo.removedPackage != null;
13828 boolean allowBackup = res.pkg != null && res.pkg.isAllowBackup();
13829 boolean doRestore = !update && allowBackup;
13831 // Set up the post-install work request bookkeeping. This will be used
13832 // and cleaned up by the post-install event handling regardless of whether
13833 // there's a restore pass performed. Token values are >= 1.
13835 if (mNextInstallToken < 0) mNextInstallToken = 1;
13836 token = mNextInstallToken++;
13837 if (data != null) {
13838 mRunningInstalls.put(token, data);
13839 } else if (DEBUG_INSTALL) {
13840 Log.v(TAG, "No post-install required for " + token);
13843 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
13845 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
13846 // Pass responsibility to the Backup Manager. It will perform a
13847 // restore if appropriate, then pass responsibility back to the
13848 // Package Manager to run the post-install observer callbacks
13850 if (res.freezer != null) {
13851 res.freezer.close();
13853 doRestore = performBackupManagerRestore(userId, token, res);
13856 // If this is an update to a package that might be potentially downgraded, then we
13857 // need to check with the rollback manager whether there's any userdata that might
13858 // need to be snapshotted or restored for the package.
13860 // TODO(narayan): Get this working for cases where userId == UserHandle.USER_ALL.
13861 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && !doRestore && update) {
13862 doRestore = performRollbackManagerRestore(userId, token, res, data);
13866 // No restore possible, or the Backup Manager was mysteriously not
13867 // available -- just fire the post-install work request directly.
13868 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
13870 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
13872 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
13873 mHandler.sendMessage(msg);
13878 * Perform Backup Manager restore for a given {@link PackageInstalledInfo}.
13879 * Returns whether the restore successfully completed.
13881 private boolean performBackupManagerRestore(int userId, int token, PackageInstalledInfo res) {
13882 IBackupManager bm = IBackupManager.Stub.asInterface(
13883 ServiceManager.getService(Context.BACKUP_SERVICE));
13885 // For backwards compatibility as USER_ALL previously routed directly to USER_SYSTEM
13886 // in the BackupManager. USER_ALL is used in compatibility tests.
13887 if (userId == UserHandle.USER_ALL) {
13888 userId = UserHandle.USER_SYSTEM;
13890 if (DEBUG_INSTALL) {
13891 Log.v(TAG, "token " + token + " to BM for possible restore for user " + userId);
13893 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13895 if (bm.isUserReadyForBackup(userId)) {
13896 bm.restoreAtInstallForUser(
13897 userId, res.pkg.getPackageName(), token);
13899 Slog.w(TAG, "User " + userId + " is not ready. Restore at install "
13900 + "didn't take place.");
13903 } catch (RemoteException e) {
13904 // can't happen; the backup manager is local
13905 } catch (Exception e) {
13906 Slog.e(TAG, "Exception trying to enqueue restore", e);
13910 Slog.e(TAG, "Backup Manager not found!");
13917 * Perform Rollback Manager restore for a given {@link PackageInstalledInfo}.
13918 * Returns whether the restore successfully completed.
13920 private boolean performRollbackManagerRestore(int userId, int token, PackageInstalledInfo res,
13921 PostInstallData data) {
13922 IRollbackManager rm = IRollbackManager.Stub.asInterface(
13923 ServiceManager.getService(Context.ROLLBACK_SERVICE));
13925 final String packageName = res.pkg.getPackageName();
13926 final int[] allUsers = mUserManager.getUserIds();
13927 final int[] installedUsers;
13929 final PackageSetting ps;
13931 long ceDataInode = -1;
13932 synchronized (mSettings) {
13933 ps = mSettings.getPackageLPr(packageName);
13936 ceDataInode = ps.getCeDataInode(userId);
13939 // NOTE: We ignore the user specified in the InstallParam because we know this is
13940 // an update, and hence need to restore data for all installed users.
13941 installedUsers = ps.queryInstalledUsers(allUsers, true);
13944 boolean doSnapshotOrRestore = data != null && data.args != null
13945 && ((data.args.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0
13946 || (data.args.installFlags & PackageManager.INSTALL_REQUEST_DOWNGRADE) != 0);
13948 if (ps != null && doSnapshotOrRestore) {
13949 final String seInfo = AndroidPackageUtils.getSeInfo(res.pkg, ps);
13951 rm.snapshotAndRestoreUserData(packageName, installedUsers, appId, ceDataInode,
13953 } catch (RemoteException re) {
13954 Log.e(TAG, "Error snapshotting/restoring user data: " + re);
13963 * Callback from PackageSettings whenever an app is first transitioned out of the
13964 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if
13965 * the app was "launched" for a restoreAtInstall operation. Therefore we check
13966 * here whether the app is the target of an ongoing install, and only send the
13967 * broadcast immediately if it is not in that state. If it *is* undergoing a restore,
13968 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
13971 void notifyFirstLaunch(final String packageName, final String installerPackage,
13972 final int userId) {
13973 // Serialize this with the rest of the install-process message chain. In the
13974 // restore-at-install case, this Runnable will necessarily run before the
13975 // POST_INSTALL message is processed, so the contents of mRunningInstalls
13976 // are coherent. In the non-restore case, the app has already completed install
13977 // and been launched through some other means, so it is not in a problematic
13978 // state for observers to see the FIRST_LAUNCH signal.
13979 mHandler.post(() -> {
13980 for (int i = 0; i < mRunningInstalls.size(); i++) {
13981 final PostInstallData data = mRunningInstalls.valueAt(i);
13982 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
13985 if (packageName.equals(data.res.pkg.getPackageName())) {
13986 // right package; but is it for the right user?
13987 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
13988 if (userId == data.res.newUsers[uIndex]) {
13989 if (DEBUG_BACKUP) {
13990 Slog.i(TAG, "Package " + packageName
13991 + " being restored so deferring FIRST_LAUNCH");
13998 // didn't find it, so not being restored
13999 if (DEBUG_BACKUP) {
14000 Slog.i(TAG, "Package " + packageName + " sending normal FIRST_LAUNCH");
14002 final boolean isInstantApp = isInstantApp(packageName, userId);
14003 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
14004 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
14005 sendFirstLaunchBroadcast(packageName, installerPackage, userIds, instantUserIds);
14009 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg,
14010 int[] userIds, int[] instantUserIds) {
14011 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14012 installerPkg, null, userIds, instantUserIds);
14015 private abstract class HandlerParams {
14016 /** User handle for the user requesting the information or installation. */
14017 private final UserHandle mUser;
14018 String traceMethod;
14021 HandlerParams(UserHandle user) {
14025 UserHandle getUser() {
14030 * Gets the user handle for the user that the rollback agent should
14031 * use to look up information about this installation when enabling
14034 UserHandle getRollbackUser() {
14035 // The session for packages installed for "all" users is
14036 // associated with the "system" user.
14037 if (mUser == UserHandle.ALL) {
14038 return UserHandle.SYSTEM;
14043 HandlerParams setTraceMethod(String traceMethod) {
14044 this.traceMethod = traceMethod;
14048 HandlerParams setTraceCookie(int traceCookie) {
14049 this.traceCookie = traceCookie;
14053 final void startCopy() {
14054 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14056 handleReturnCode();
14059 abstract void handleStartCopy();
14060 abstract void handleReturnCode();
14063 static class OriginInfo {
14065 * Location where install is coming from, before it has been
14066 * copied/renamed into place. This could be a single monolithic APK
14067 * file, or a cluster directory. This location may be untrusted.
14072 * Flag indicating that {@link #file} has already been staged, meaning downstream users
14073 * don't need to defensively copy the contents.
14075 final boolean staged;
14078 * Flag indicating that {@link #file} is an already installed app that is being moved.
14080 final boolean existing;
14082 final String resolvedPath;
14083 final File resolvedFile;
14085 static OriginInfo fromNothing() {
14086 return new OriginInfo(null, false, false);
14089 static OriginInfo fromUntrustedFile(File file) {
14090 return new OriginInfo(file, false, false);
14093 static OriginInfo fromExistingFile(File file) {
14094 return new OriginInfo(file, false, true);
14097 static OriginInfo fromStagedFile(File file) {
14098 return new OriginInfo(file, true, false);
14101 private OriginInfo(File file, boolean staged, boolean existing) {
14103 this.staged = staged;
14104 this.existing = existing;
14106 if (file != null) {
14107 resolvedPath = file.getAbsolutePath();
14108 resolvedFile = file;
14110 resolvedPath = null;
14111 resolvedFile = null;
14116 static class MoveInfo {
14118 final String fromUuid;
14119 final String toUuid;
14120 final String packageName;
14122 final String seinfo;
14123 final int targetSdkVersion;
14124 final String fromCodePath;
14126 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14127 int appId, String seinfo, int targetSdkVersion,
14128 String fromCodePath) {
14129 this.moveId = moveId;
14130 this.fromUuid = fromUuid;
14131 this.toUuid = toUuid;
14132 this.packageName = packageName;
14133 this.appId = appId;
14134 this.seinfo = seinfo;
14135 this.targetSdkVersion = targetSdkVersion;
14136 this.fromCodePath = fromCodePath;
14140 static class VerificationInfo {
14141 /** A constant used to indicate that a uid value is not present. */
14142 public static final int NO_UID = -1;
14144 /** URI referencing where the package was downloaded from. */
14145 final Uri originatingUri;
14147 /** HTTP referrer URI associated with the originatingURI. */
14148 final Uri referrer;
14150 /** UID of the application that the install request originated from. */
14151 final int originatingUid;
14153 /** UID of application requesting the install */
14154 final int installerUid;
14156 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14157 this.originatingUri = originatingUri;
14158 this.referrer = referrer;
14159 this.originatingUid = originatingUid;
14160 this.installerUid = installerUid;
14165 * Container for a multi-package install which refers to all install sessions and args being
14166 * committed together.
14168 class MultiPackageInstallParams extends HandlerParams {
14170 private int mRet = INSTALL_SUCCEEDED;
14172 private final ArrayList<InstallParams> mChildParams;
14174 private final Map<InstallArgs, Integer> mCurrentState;
14176 MultiPackageInstallParams(
14177 @NonNull UserHandle user,
14178 @NonNull List<ActiveInstallSession> activeInstallSessions)
14179 throws PackageManagerException {
14181 if (activeInstallSessions.size() == 0) {
14182 throw new PackageManagerException("No child sessions found!");
14184 mChildParams = new ArrayList<>(activeInstallSessions.size());
14185 for (int i = 0; i < activeInstallSessions.size(); i++) {
14186 final InstallParams childParams = new InstallParams(activeInstallSessions.get(i));
14187 childParams.mParentInstallParams = this;
14188 this.mChildParams.add(childParams);
14190 this.mCurrentState = new ArrayMap<>(mChildParams.size());
14194 void handleStartCopy() {
14195 for (InstallParams params : mChildParams) {
14196 params.handleStartCopy();
14197 if (params.mRet != INSTALL_SUCCEEDED) {
14198 mRet = params.mRet;
14204 void handleReturnCode() {
14205 for (InstallParams params : mChildParams) {
14206 params.handleReturnCode();
14207 if (params.mRet != INSTALL_SUCCEEDED) {
14208 mRet = params.mRet;
14213 void tryProcessInstallRequest(InstallArgs args, int currentStatus) {
14214 mCurrentState.put(args, currentStatus);
14215 if (mCurrentState.size() != mChildParams.size()) {
14218 int completeStatus = PackageManager.INSTALL_SUCCEEDED;
14219 for (Integer status : mCurrentState.values()) {
14220 if (status == PackageManager.INSTALL_UNKNOWN) {
14222 } else if (status != PackageManager.INSTALL_SUCCEEDED) {
14223 completeStatus = status;
14227 final List<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size());
14228 for (Map.Entry<InstallArgs, Integer> entry : mCurrentState.entrySet()) {
14229 installRequests.add(new InstallRequest(entry.getKey(),
14230 createPackageInstalledInfo(completeStatus)));
14232 processInstallRequestsAsync(
14233 completeStatus == PackageManager.INSTALL_SUCCEEDED,
14238 class InstallParams extends HandlerParams {
14239 // TODO: see if we can collapse this into ActiveInstallSession
14241 final OriginInfo origin;
14242 final MoveInfo move;
14243 final IPackageInstallObserver2 observer;
14245 @NonNull final InstallSource installSource;
14246 final String volumeUuid;
14247 private boolean mVerificationCompleted;
14248 private boolean mIntegrityVerificationCompleted;
14249 private boolean mEnableRollbackCompleted;
14250 private InstallArgs mArgs;
14252 final String packageAbiOverride;
14253 final String[] grantedRuntimePermissions;
14254 final List<String> whitelistedRestrictedPermissions;
14255 final VerificationInfo verificationInfo;
14256 final PackageParser.SigningDetails signingDetails;
14257 final int installReason;
14259 MultiPackageInstallParams mParentInstallParams;
14260 final long requiredInstalledVersionCode;
14261 final boolean forceQueryableOverride;
14262 final int mDataLoaderType;
14264 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14265 int installFlags, InstallSource installSource, String volumeUuid,
14266 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14267 String[] grantedPermissions, List<String> whitelistedRestrictedPermissions,
14268 SigningDetails signingDetails, int installReason,
14269 long requiredInstalledVersionCode, int dataLoaderType) {
14271 this.origin = origin;
14273 this.observer = observer;
14274 this.installFlags = installFlags;
14275 this.installSource = Preconditions.checkNotNull(installSource);
14276 this.volumeUuid = volumeUuid;
14277 this.verificationInfo = verificationInfo;
14278 this.packageAbiOverride = packageAbiOverride;
14279 this.grantedRuntimePermissions = grantedPermissions;
14280 this.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
14281 this.signingDetails = signingDetails;
14282 this.installReason = installReason;
14283 this.requiredInstalledVersionCode = requiredInstalledVersionCode;
14284 this.forceQueryableOverride = false;
14285 this.mDataLoaderType = dataLoaderType;
14288 InstallParams(ActiveInstallSession activeInstallSession) {
14289 super(activeInstallSession.getUser());
14290 final PackageInstaller.SessionParams sessionParams =
14291 activeInstallSession.getSessionParams();
14292 if (DEBUG_INSTANT) {
14293 if ((sessionParams.installFlags
14294 & PackageManager.INSTALL_INSTANT_APP) != 0) {
14295 Slog.d(TAG, "Ephemeral install of " + activeInstallSession.getPackageName());
14298 verificationInfo = new VerificationInfo(
14299 sessionParams.originatingUri,
14300 sessionParams.referrerUri,
14301 sessionParams.originatingUid,
14302 activeInstallSession.getInstallerUid());
14303 origin = OriginInfo.fromStagedFile(activeInstallSession.getStagedDir());
14305 installReason = fixUpInstallReason(
14306 activeInstallSession.getInstallSource().installerPackageName,
14307 activeInstallSession.getInstallerUid(),
14308 sessionParams.installReason);
14309 observer = activeInstallSession.getObserver();
14310 installFlags = sessionParams.installFlags;
14311 installSource = activeInstallSession.getInstallSource();
14312 volumeUuid = sessionParams.volumeUuid;
14313 packageAbiOverride = sessionParams.abiOverride;
14314 grantedRuntimePermissions = sessionParams.grantedRuntimePermissions;
14315 whitelistedRestrictedPermissions = sessionParams.whitelistedRestrictedPermissions;
14316 signingDetails = activeInstallSession.getSigningDetails();
14317 requiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode;
14318 forceQueryableOverride = sessionParams.forceQueryableOverride;
14319 mDataLoaderType = (sessionParams.dataLoaderParams != null)
14320 ? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE;
14324 public String toString() {
14325 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14326 + " file=" + origin.file + "}";
14329 private int installLocationPolicy(PackageInfoLite pkgLite) {
14330 String packageName = pkgLite.packageName;
14331 int installLocation = pkgLite.installLocation;
14333 synchronized (mLock) {
14334 // Currently installed package which the new package is attempting to replace or
14335 // null if no such package is installed.
14336 AndroidPackage installedPkg = mPackages.get(packageName);
14337 // Package which currently owns the data which the new package will own if installed.
14338 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14339 // will be null whereas dataOwnerPkg will contain information about the package
14340 // which was uninstalled while keeping its data.
14341 AndroidPackage dataOwnerPkg = installedPkg;
14342 if (dataOwnerPkg == null) {
14343 PackageSetting ps = mSettings.mPackages.get(packageName);
14345 dataOwnerPkg = ps.pkg;
14349 if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST) {
14350 if (dataOwnerPkg == null) {
14351 Slog.w(TAG, "Required installed version code was "
14352 + requiredInstalledVersionCode
14353 + " but package is not installed");
14354 return PackageHelper.RECOMMEND_FAILED_WRONG_INSTALLED_VERSION;
14357 if (dataOwnerPkg.getLongVersionCode() != requiredInstalledVersionCode) {
14358 Slog.w(TAG, "Required installed version code was "
14359 + requiredInstalledVersionCode
14360 + " but actual installed version is "
14361 + dataOwnerPkg.getLongVersionCode());
14362 return PackageHelper.RECOMMEND_FAILED_WRONG_INSTALLED_VERSION;
14366 if (dataOwnerPkg != null) {
14367 if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags,
14368 dataOwnerPkg.isDebuggable())) {
14370 checkDowngrade(dataOwnerPkg, pkgLite);
14371 } catch (PackageManagerException e) {
14372 Slog.w(TAG, "Downgrade detected: " + e.getMessage());
14373 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
14378 if (installedPkg != null) {
14379 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
14380 // Check for updated system application.
14381 if (installedPkg.isSystem()) {
14382 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14384 // If current upgrade specifies particular preference
14385 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
14386 // Application explicitly specified internal.
14387 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14388 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
14389 // App explictly prefers external. Let policy decide
14391 // Prefer previous location
14392 if (installedPkg.isExternalStorage()) {
14393 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14395 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14399 // Invalid install. Return error code
14400 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
14404 return pkgLite.recommendedInstallLocation;
14408 * Invoke remote method to get package information and install
14409 * location values. Override install location based on default
14410 * policy if needed and then create install arguments based
14411 * on the install location.
14413 public void handleStartCopy() {
14414 int ret = PackageManager.INSTALL_SUCCEEDED;
14416 // If we're already staged, we've firmly committed to an install location
14417 if (origin.staged) {
14418 if (origin.file != null) {
14419 installFlags |= PackageManager.INSTALL_INTERNAL;
14421 throw new IllegalStateException("Invalid stage location");
14425 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
14426 final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14427 PackageInfoLite pkgLite = null;
14430 pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
14431 origin.resolvedPath, installFlags, packageAbiOverride);
14433 if (DEBUG_INSTANT && ephemeral) {
14434 Slog.v(TAG, "pkgLite for install: " + pkgLite);
14438 * If we have too little free space, try to free cache
14439 * before giving up.
14441 if (!origin.staged && pkgLite.recommendedInstallLocation
14442 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14443 // TODO: focus freeing disk space on the target device
14444 final StorageManager storage = StorageManager.from(mContext);
14445 final long lowThreshold = storage.getStorageLowBytes(
14446 Environment.getDataDirectory());
14448 final long sizeBytes = PackageManagerServiceUtils.calculateInstalledSize(
14449 origin.resolvedPath, packageAbiOverride);
14450 if (sizeBytes >= 0) {
14452 mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
14453 pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
14454 origin.resolvedPath, installFlags, packageAbiOverride);
14455 } catch (InstallerException e) {
14456 Slog.w(TAG, "Failed to free cache", e);
14461 * The cache free must have deleted the file we downloaded to install.
14463 * TODO: fix the "freeCache" call to not delete the file we care about.
14465 if (pkgLite.recommendedInstallLocation
14466 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14467 pkgLite.recommendedInstallLocation
14468 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
14473 if (ret == PackageManager.INSTALL_SUCCEEDED) {
14474 int loc = pkgLite.recommendedInstallLocation;
14475 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
14476 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14477 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
14478 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
14479 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14480 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
14481 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
14482 ret = PackageManager.INSTALL_FAILED_INVALID_APK;
14483 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14484 ret = PackageManager.INSTALL_FAILED_INVALID_URI;
14485 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
14486 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
14488 // Override with defaults if needed.
14489 loc = installLocationPolicy(pkgLite);
14490 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
14491 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
14492 } else if (loc == PackageHelper.RECOMMEND_FAILED_WRONG_INSTALLED_VERSION) {
14493 ret = PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION;
14494 } else if (!onInt) {
14495 // Override install location with flags
14496 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
14497 // Set the flag to install on external media.
14498 installFlags &= ~PackageManager.INSTALL_INTERNAL;
14499 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
14500 if (DEBUG_INSTANT) {
14501 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
14503 installFlags |= PackageManager.INSTALL_INSTANT_APP;
14504 installFlags &= ~PackageManager.INSTALL_INTERNAL;
14506 // Make sure the flag for installing on external
14508 installFlags |= PackageManager.INSTALL_INTERNAL;
14514 final InstallArgs args = createInstallArgs(this);
14515 mVerificationCompleted = true;
14516 mIntegrityVerificationCompleted = true;
14517 mEnableRollbackCompleted = true;
14520 if (ret == PackageManager.INSTALL_SUCCEEDED) {
14521 final int verificationId = mPendingVerificationToken++;
14523 // Perform package verification (unless we are simply moving the package).
14524 if (!origin.existing) {
14525 PackageVerificationState verificationState =
14526 new PackageVerificationState(this);
14527 mPendingVerification.append(verificationId, verificationState);
14529 sendIntegrityVerificationRequest(verificationId, pkgLite, verificationState);
14530 ret = sendPackageVerificationRequest(
14531 verificationId, pkgLite, verificationState);
14533 // If both verifications are skipped, we should remove the state.
14534 if (verificationState.areAllVerificationsComplete()) {
14535 mPendingVerification.remove(verificationId);
14540 if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
14541 // TODO(ruhler) b/112431924: Don't do this in case of 'move'?
14542 final int enableRollbackToken = mPendingEnableRollbackToken++;
14543 Trace.asyncTraceBegin(
14544 TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
14545 mPendingEnableRollback.append(enableRollbackToken, this);
14547 Intent enableRollbackIntent = new Intent(Intent.ACTION_PACKAGE_ENABLE_ROLLBACK);
14548 enableRollbackIntent.putExtra(
14549 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN,
14550 enableRollbackToken);
14551 enableRollbackIntent.putExtra(
14552 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALL_FLAGS,
14554 enableRollbackIntent.putExtra(
14555 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_USER,
14556 getRollbackUser().getIdentifier());
14557 enableRollbackIntent.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14558 PACKAGE_MIME_TYPE);
14559 enableRollbackIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14561 // Allow the broadcast to be sent before boot complete.
14562 // This is needed when committing the apk part of a staged
14563 // session in early boot. The rollback manager registers
14564 // its receiver early enough during the boot process that
14565 // it will not miss the broadcast.
14566 enableRollbackIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
14568 mContext.sendOrderedBroadcastAsUser(enableRollbackIntent, UserHandle.SYSTEM,
14569 android.Manifest.permission.PACKAGE_ROLLBACK_AGENT,
14570 new BroadcastReceiver() {
14572 public void onReceive(Context context, Intent intent) {
14573 // the duration to wait for rollback to be enabled, in millis
14574 long rollbackTimeout = DeviceConfig.getLong(
14575 DeviceConfig.NAMESPACE_ROLLBACK,
14576 PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS,
14577 DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS);
14578 if (rollbackTimeout < 0) {
14579 rollbackTimeout = DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS;
14581 final Message msg = mHandler.obtainMessage(
14582 ENABLE_ROLLBACK_TIMEOUT);
14583 msg.arg1 = enableRollbackToken;
14584 mHandler.sendMessageDelayed(msg, rollbackTimeout);
14586 }, null, 0, null, null);
14588 mEnableRollbackCompleted = false;
14596 * Send a request to check the integrity of the package.
14598 void sendIntegrityVerificationRequest(
14599 int verificationId,
14600 PackageInfoLite pkgLite,
14601 PackageVerificationState verificationState) {
14602 if (!isIntegrityVerificationEnabled()) {
14603 // Consider the integrity check as passed.
14604 verificationState.setIntegrityVerificationResult(
14605 PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
14609 final Intent integrityVerification =
14610 new Intent(Intent.ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
14612 integrityVerification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14613 PACKAGE_MIME_TYPE);
14615 final int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
14616 | Intent.FLAG_RECEIVER_REGISTERED_ONLY
14617 | Intent.FLAG_RECEIVER_FOREGROUND;
14618 integrityVerification.addFlags(flags);
14620 integrityVerification.putExtra(EXTRA_VERIFICATION_ID, verificationId);
14621 integrityVerification.putExtra(EXTRA_PACKAGE_NAME, pkgLite.packageName);
14622 integrityVerification.putExtra(EXTRA_VERSION_CODE, pkgLite.versionCode);
14623 integrityVerification.putExtra(EXTRA_LONG_VERSION_CODE, pkgLite.getLongVersionCode());
14624 populateInstallerExtras(integrityVerification);
14626 // send to integrity component only.
14627 integrityVerification.setPackage("android");
14629 DeviceIdleInternal idleController =
14630 mInjector.getLocalDeviceIdleController();
14631 final long idleDuration = getVerificationTimeout();
14633 idleController.addPowerSaveTempWhitelistAppDirect(Process.myUid(),
14635 false, "integrity component");
14636 mContext.sendOrderedBroadcastAsUser(integrityVerification, UserHandle.SYSTEM,
14637 /* receiverPermission= */ null,
14638 new BroadcastReceiver() {
14640 public void onReceive(Context context, Intent intent) {
14641 final Message msg =
14642 mHandler.obtainMessage(CHECK_PENDING_INTEGRITY_VERIFICATION);
14643 msg.arg1 = verificationId;
14644 // TODO: do we want to use the same timeout?
14645 mHandler.sendMessageDelayed(msg, getVerificationTimeout());
14647 }, /* scheduler= */ null,
14648 /* initialCode= */ 0,
14649 /* initialData= */ null,
14650 /* initialExtras= */ null);
14652 Trace.asyncTraceBegin(
14653 TRACE_TAG_PACKAGE_MANAGER, "integrity_verification", verificationId);
14655 // stop the copy until verification succeeds.
14656 mIntegrityVerificationCompleted = false;
14660 * Send a request to verifier(s) to verify the package if necessary, and return
14661 * {@link PackageManager#INSTALL_SUCCEEDED} if succeeded.
14663 int sendPackageVerificationRequest(
14664 int verificationId,
14665 PackageInfoLite pkgLite,
14666 PackageVerificationState verificationState) {
14667 int ret = INSTALL_SUCCEEDED;
14669 // TODO: http://b/22976637
14670 // Apps installed for "all" users use the device owner to verify the app
14671 UserHandle verifierUser = getUser();
14672 if (verifierUser == UserHandle.ALL) {
14673 verifierUser = UserHandle.SYSTEM;
14677 * Determine if we have any installed package verifiers. If we
14678 * do, then we'll defer to them to verify the packages.
14680 final int requiredUid = mRequiredVerifierPackage == null ? -1
14681 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
14682 verifierUser.getIdentifier());
14683 verificationState.setRequiredVerifierUid(requiredUid);
14684 final int installerUid =
14685 verificationInfo == null ? -1 : verificationInfo.installerUid;
14686 if (!origin.existing && requiredUid != -1
14687 && isVerificationEnabled(
14688 pkgLite, verifierUser.getIdentifier(), installFlags, installerUid)) {
14689 final Intent verification = new Intent(
14690 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
14691 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14692 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14693 PACKAGE_MIME_TYPE);
14694 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14696 // Query all live verifiers based on current user state
14697 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
14698 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
14699 false /*allowDynamicSplits*/);
14701 if (DEBUG_VERIFY) {
14702 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
14703 + verification.toString() + " with " + pkgLite.verifiers.length
14704 + " optional verifiers");
14707 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14709 verification.putExtra(
14710 PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, installFlags);
14712 verification.putExtra(
14713 PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, pkgLite.packageName);
14715 verification.putExtra(
14716 PackageManager.EXTRA_VERIFICATION_VERSION_CODE, pkgLite.versionCode);
14718 verification.putExtra(
14719 PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
14720 pkgLite.getLongVersionCode());
14722 populateInstallerExtras(verification);
14724 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
14725 receivers, verificationState);
14727 DeviceIdleInternal idleController =
14728 mInjector.getLocalDeviceIdleController();
14729 final long idleDuration = getVerificationTimeout();
14732 * If any sufficient verifiers were listed in the package
14733 * manifest, attempt to ask them.
14735 if (sufficientVerifiers != null) {
14736 final int n = sufficientVerifiers.size();
14738 Slog.i(TAG, "Additional verifiers required, but none installed.");
14739 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
14741 for (int i = 0; i < n; i++) {
14742 final ComponentName verifierComponent = sufficientVerifiers.get(i);
14743 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14744 verifierComponent.getPackageName(), idleDuration,
14745 verifierUser.getIdentifier(), false, "package verifier");
14747 final Intent sufficientIntent = new Intent(verification);
14748 sufficientIntent.setComponent(verifierComponent);
14749 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
14754 final ComponentName requiredVerifierComponent = matchComponentForVerifier(
14755 mRequiredVerifierPackage, receivers);
14756 if (mRequiredVerifierPackage != null) {
14758 * Send the intent to the required verification agent,
14759 * but only start the verification timeout after the
14760 * target BroadcastReceivers have run.
14762 verification.setComponent(requiredVerifierComponent);
14763 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14764 mRequiredVerifierPackage, idleDuration,
14765 verifierUser.getIdentifier(), false, "package verifier");
14766 mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
14767 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14768 new BroadcastReceiver() {
14770 public void onReceive(Context context, Intent intent) {
14771 final Message msg = mHandler
14772 .obtainMessage(CHECK_PENDING_VERIFICATION);
14773 msg.arg1 = verificationId;
14774 mHandler.sendMessageDelayed(msg, getVerificationTimeout());
14776 }, null, 0, null, null);
14778 Trace.asyncTraceBegin(
14779 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
14782 * We don't want the copy to proceed until verification
14785 mVerificationCompleted = false;
14788 verificationState.setVerifierResponse(
14789 requiredUid, PackageManager.VERIFICATION_ALLOW);
14794 void populateInstallerExtras(Intent intent) {
14795 intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
14796 installSource.initiatingPackageName);
14798 if (verificationInfo != null) {
14799 if (verificationInfo.originatingUri != null) {
14800 intent.putExtra(Intent.EXTRA_ORIGINATING_URI,
14801 verificationInfo.originatingUri);
14803 if (verificationInfo.referrer != null) {
14804 intent.putExtra(Intent.EXTRA_REFERRER,
14805 verificationInfo.referrer);
14807 if (verificationInfo.originatingUid >= 0) {
14808 intent.putExtra(Intent.EXTRA_ORIGINATING_UID,
14809 verificationInfo.originatingUid);
14811 if (verificationInfo.installerUid >= 0) {
14812 intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
14813 verificationInfo.installerUid);
14818 void setReturnCode(int ret) {
14819 if (mRet == PackageManager.INSTALL_SUCCEEDED) {
14820 // Only update mRet if it was previously INSTALL_SUCCEEDED to
14821 // ensure we do not overwrite any previous failure results.
14826 void handleVerificationFinished() {
14827 if (!mVerificationCompleted) {
14828 mVerificationCompleted = true;
14829 if (mIntegrityVerificationCompleted) {
14830 handleReturnCode();
14832 // integrity verification still pending.
14836 void handleIntegrityVerificationFinished() {
14837 if (!mIntegrityVerificationCompleted) {
14838 mIntegrityVerificationCompleted = true;
14839 if (mVerificationCompleted) {
14840 handleReturnCode();
14842 // verifier still pending
14847 void handleRollbackEnabled() {
14848 // TODO(ruhler) b/112431924: Consider halting the install if we
14849 // couldn't enable rollback.
14850 mEnableRollbackCompleted = true;
14851 handleReturnCode();
14855 void handleReturnCode() {
14856 if (mVerificationCompleted
14857 && mIntegrityVerificationCompleted && mEnableRollbackCompleted) {
14858 if ((installFlags & PackageManager.INSTALL_DRY_RUN) != 0) {
14859 String packageName = "";
14861 PackageLite packageInfo =
14862 new PackageParser().parsePackageLite(origin.file, 0);
14863 packageName = packageInfo.packageName;
14864 } catch (PackageParserException e) {
14865 Slog.e(TAG, "Can't parse package at " + origin.file.getAbsolutePath(), e);
14868 observer.onPackageInstalled(packageName, mRet, "Dry run", new Bundle());
14869 } catch (RemoteException e) {
14870 Slog.i(TAG, "Observer no longer exists.");
14874 if (mRet == PackageManager.INSTALL_SUCCEEDED) {
14875 mRet = mArgs.copyApk();
14877 processPendingInstall(mArgs, mRet);
14882 private InstallArgs createInstallArgs(InstallParams params) {
14883 if (params.move != null) {
14884 return new MoveInstallArgs(params);
14886 return new FileInstallArgs(params);
14891 * Create args that describe an existing installed package. Typically used
14892 * when cleaning up old installs, or used as a move source.
14894 private InstallArgs createInstallArgsForExisting(String codePath,
14895 String resourcePath, String[] instructionSets) {
14896 return new FileInstallArgs(codePath, resourcePath, instructionSets);
14899 static abstract class InstallArgs {
14900 /** @see InstallParams#origin */
14901 final OriginInfo origin;
14902 /** @see InstallParams#move */
14903 final MoveInfo move;
14905 final IPackageInstallObserver2 observer;
14906 // Always refers to PackageManager flags only
14907 final int installFlags;
14908 @NonNull final InstallSource installSource;
14909 final String volumeUuid;
14910 final UserHandle user;
14911 final String abiOverride;
14912 final String[] installGrantPermissions;
14913 final List<String> whitelistedRestrictedPermissions;
14914 /** If non-null, drop an async trace when the install completes */
14915 final String traceMethod;
14916 final int traceCookie;
14917 final PackageParser.SigningDetails signingDetails;
14918 final int installReason;
14919 final boolean forceQueryableOverride;
14920 @Nullable final MultiPackageInstallParams mMultiPackageInstallParams;
14921 final int mDataLoaderType;
14923 // The list of instruction sets supported by this app. This is currently
14924 // only used during the rmdex() phase to clean up resources. We can get rid of this
14925 // if we move dex files under the common app path.
14926 /* nullable */ String[] instructionSets;
14928 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14929 int installFlags, InstallSource installSource, String volumeUuid,
14930 UserHandle user, String[] instructionSets,
14931 String abiOverride, String[] installGrantPermissions,
14932 List<String> whitelistedRestrictedPermissions,
14933 String traceMethod, int traceCookie, SigningDetails signingDetails,
14934 int installReason, boolean forceQueryableOverride,
14935 MultiPackageInstallParams multiPackageInstallParams, int dataLoaderType) {
14936 this.origin = origin;
14938 this.installFlags = installFlags;
14939 this.observer = observer;
14940 this.installSource = Preconditions.checkNotNull(installSource);
14941 this.volumeUuid = volumeUuid;
14943 this.instructionSets = instructionSets;
14944 this.abiOverride = abiOverride;
14945 this.installGrantPermissions = installGrantPermissions;
14946 this.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
14947 this.traceMethod = traceMethod;
14948 this.traceCookie = traceCookie;
14949 this.signingDetails = signingDetails;
14950 this.installReason = installReason;
14951 this.forceQueryableOverride = forceQueryableOverride;
14952 this.mMultiPackageInstallParams = multiPackageInstallParams;
14953 this.mDataLoaderType = dataLoaderType;
14957 InstallArgs(InstallParams params) {
14958 this(params.origin, params.move, params.observer, params.installFlags,
14959 params.installSource, params.volumeUuid,
14960 params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
14961 params.grantedRuntimePermissions, params.whitelistedRestrictedPermissions,
14962 params.traceMethod, params.traceCookie, params.signingDetails,
14963 params.installReason, params.forceQueryableOverride,
14964 params.mParentInstallParams, params.mDataLoaderType);
14967 abstract int copyApk();
14968 abstract int doPreInstall(int status);
14971 * Rename package into final resting place. All paths on the given
14972 * scanned package should be updated to reflect the rename.
14974 abstract boolean doRename(int status, ParsedPackage parsedPackage);
14975 abstract int doPostInstall(int status, int uid);
14977 /** @see PackageSettingBase#codePathString */
14978 abstract String getCodePath();
14979 /** @see PackageSettingBase#resourcePathString */
14980 abstract String getResourcePath();
14982 // Need installer lock especially for dex file removal.
14983 abstract void cleanUpResourcesLI();
14984 abstract boolean doPostDeleteLI(boolean delete);
14987 * Called before the source arguments are copied. This is used mostly
14988 * for MoveParams when it needs to read the source file to put it in the
14992 return PackageManager.INSTALL_SUCCEEDED;
14996 * Called after the source arguments are copied. This is used mostly for
14997 * MoveParams when it needs to read the source file to put it in the
15000 int doPostCopy(int uid) {
15001 return PackageManager.INSTALL_SUCCEEDED;
15004 protected boolean isEphemeral() {
15005 return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15008 UserHandle getUser() {
15013 void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15014 if (!allCodePaths.isEmpty()) {
15015 if (instructionSets == null) {
15016 throw new IllegalStateException("instructionSet == null");
15018 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15019 for (String codePath : allCodePaths) {
15020 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15022 mInstaller.rmdex(codePath, dexCodeInstructionSet);
15023 } catch (InstallerException ignored) {
15031 * Logic to handle installation of new applications, including copying
15032 * and renaming logic.
15034 class FileInstallArgs extends InstallArgs {
15035 private File codeFile;
15036 private File resourceFile;
15038 // Example topology:
15039 // /data/app/com.example/base.apk
15040 // /data/app/com.example/split_foo.apk
15041 // /data/app/com.example/lib/arm/libfoo.so
15042 // /data/app/com.example/lib/arm64/libfoo.so
15043 // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15046 FileInstallArgs(InstallParams params) {
15050 /** Existing install */
15051 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15052 super(OriginInfo.fromNothing(), null, null, 0, InstallSource.EMPTY,
15053 null, null, instructionSets, null, null, null, null, 0,
15054 PackageParser.SigningDetails.UNKNOWN,
15055 PackageManager.INSTALL_REASON_UNKNOWN, false, null /* parent */,
15056 DataLoaderType.NONE);
15057 this.codeFile = (codePath != null) ? new File(codePath) : null;
15058 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15062 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15064 return doCopyApk();
15066 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15070 private int doCopyApk() {
15071 if (origin.staged) {
15072 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15073 codeFile = origin.file;
15074 resourceFile = origin.file;
15075 return PackageManager.INSTALL_SUCCEEDED;
15079 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15080 final File tempDir =
15081 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15082 codeFile = tempDir;
15083 resourceFile = tempDir;
15084 } catch (IOException e) {
15085 Slog.w(TAG, "Failed to create copy file: " + e);
15086 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15089 int ret = PackageManagerServiceUtils.copyPackage(
15090 origin.file.getAbsolutePath(), codeFile);
15091 if (ret != PackageManager.INSTALL_SUCCEEDED) {
15092 Slog.e(TAG, "Failed to copy package");
15096 final boolean isIncremental = isIncrementalPath(codeFile.getAbsolutePath());
15097 final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15098 NativeLibraryHelper.Handle handle = null;
15100 handle = NativeLibraryHelper.Handle.create(codeFile);
15101 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15102 abiOverride, isIncremental);
15103 } catch (IOException e) {
15104 Slog.e(TAG, "Copying native libraries failed", e);
15105 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15107 IoUtils.closeQuietly(handle);
15113 int doPreInstall(int status) {
15114 if (status != PackageManager.INSTALL_SUCCEEDED) {
15121 boolean doRename(int status, ParsedPackage parsedPackage) {
15122 if (status != PackageManager.INSTALL_SUCCEEDED) {
15127 final File targetDir = codeFile.getParentFile();
15128 final File beforeCodeFile = codeFile;
15129 final File afterCodeFile = getNextCodePath(targetDir, parsedPackage.getPackageName());
15131 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15132 final boolean onIncremental = mIncrementalManager != null
15133 && isIncrementalPath(beforeCodeFile.getAbsolutePath());
15135 makeDirRecursive(afterCodeFile.getParentFile(), 0775);
15136 if (onIncremental) {
15137 mIncrementalManager.renameCodePath(beforeCodeFile, afterCodeFile);
15139 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15141 } catch (IOException | ErrnoException e) {
15142 Slog.w(TAG, "Failed to rename", e);
15146 //TODO(b/136132412): enable selinux restorecon for incremental directories
15147 if (!onIncremental && !SELinux.restoreconRecursive(afterCodeFile)) {
15148 Slog.w(TAG, "Failed to restorecon");
15152 // Reflect the rename internally
15153 codeFile = afterCodeFile;
15154 resourceFile = afterCodeFile;
15156 // Reflect the rename in scanned details
15158 parsedPackage.setCodePath(afterCodeFile.getCanonicalPath());
15159 } catch (IOException e) {
15160 Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
15163 parsedPackage.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15164 afterCodeFile, parsedPackage.getBaseCodePath()));
15165 parsedPackage.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15166 afterCodeFile, parsedPackage.getSplitCodePaths()));
15171 int doPostInstall(int status, int uid) {
15172 if (status != PackageManager.INSTALL_SUCCEEDED) {
15179 String getCodePath() {
15180 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15184 String getResourcePath() {
15185 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15188 private boolean cleanUp() {
15189 if (codeFile == null || !codeFile.exists()) {
15193 String codePath = codeFile.getAbsolutePath();
15194 if (mIncrementalManager != null && isIncrementalPath(codePath)) {
15195 mIncrementalManager.closeStorage(codePath);
15198 removeCodePathLI(codeFile);
15200 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15201 resourceFile.delete();
15207 void cleanUpResourcesLI() {
15208 // Try enumerating all code paths before deleting
15209 List<String> allCodePaths = Collections.EMPTY_LIST;
15210 if (codeFile != null && codeFile.exists()) {
15212 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15213 allCodePaths = pkg.getAllCodePaths();
15214 } catch (PackageParserException e) {
15215 // Ignored; we tried our best
15220 removeDexFiles(allCodePaths, instructionSets);
15223 boolean doPostDeleteLI(boolean delete) {
15224 // XXX err, shouldn't we respect the delete flag?
15225 cleanUpResourcesLI();
15231 * Logic to handle movement of existing installed applications.
15233 class MoveInstallArgs extends InstallArgs {
15234 private File codeFile;
15235 private File resourceFile;
15238 MoveInstallArgs(InstallParams params) {
15243 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15244 + move.fromUuid + " to " + move.toUuid);
15245 synchronized (mInstaller) {
15247 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15248 move.appId, move.seinfo, move.targetSdkVersion,
15249 move.fromCodePath);
15250 } catch (InstallerException e) {
15251 Slog.w(TAG, "Failed to move app", e);
15252 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15256 final String toPathName = new File(move.fromCodePath).getName();
15257 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), toPathName);
15258 resourceFile = codeFile;
15259 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15261 return PackageManager.INSTALL_SUCCEEDED;
15264 int doPreInstall(int status) {
15265 if (status != PackageManager.INSTALL_SUCCEEDED) {
15266 cleanUp(move.toUuid);
15272 boolean doRename(int status, ParsedPackage parsedPackage) {
15273 if (status != PackageManager.INSTALL_SUCCEEDED) {
15274 cleanUp(move.toUuid);
15281 int doPostInstall(int status, int uid) {
15282 if (status == PackageManager.INSTALL_SUCCEEDED) {
15283 cleanUp(move.fromUuid);
15285 cleanUp(move.toUuid);
15291 String getCodePath() {
15292 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15296 String getResourcePath() {
15297 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15300 private boolean cleanUp(String volumeUuid) {
15301 final String toPathName = new File(move.fromCodePath).getName();
15302 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15304 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15305 final int[] userIds = mUserManager.getUserIds();
15306 synchronized (mInstallLock) {
15307 // Clean up both app data and code
15308 // All package moves are frozen until finished
15310 // We purposefully exclude FLAG_STORAGE_EXTERNAL here, since
15311 // this task was only focused on moving data on internal storage.
15312 // We don't want ART profiles cleared, because they don't move,
15313 // so we would be deleting the only copy (b/149200535).
15314 final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE
15315 | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES;
15316 for (int userId : userIds) {
15318 mInstaller.destroyAppData(volumeUuid, move.packageName, userId, flags, 0);
15319 } catch (InstallerException e) {
15320 Slog.w(TAG, String.valueOf(e));
15323 removeCodePathLI(codeFile);
15328 void cleanUpResourcesLI() {
15329 throw new UnsupportedOperationException();
15332 boolean doPostDeleteLI(boolean delete) {
15333 throw new UnsupportedOperationException();
15338 * Given {@code targetDir}, returns {@code targetDir/~~[randomStrA]/[packageName]-[randomStrB].}
15339 * Makes sure that {@code targetDir/~~[randomStrA]} directory doesn't exist.
15340 * Notice that this method doesn't actually create any directory.
15342 * @param targetDir Directory that is two-levels up from the result directory.
15343 * @param packageName Name of the package whose code files are to be installed under the result
15345 * @return File object for the directory that should hold the code files of {@code packageName}.
15347 private File getNextCodePath(File targetDir, String packageName) {
15348 SecureRandom random = new SecureRandom();
15349 byte[] bytes = new byte[16];
15350 File firstLevelDir;
15352 random.nextBytes(bytes);
15353 String dirName = RANDOM_DIR_PREFIX
15354 + Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15355 firstLevelDir = new File(targetDir, dirName);
15356 } while (firstLevelDir.exists());
15357 random.nextBytes(bytes);
15358 String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15359 return new File(firstLevelDir, packageName + "-" + suffix);
15362 static class PackageInstalledInfo {
15365 // The set of users that originally had this package installed.
15367 // The set of users that now have this package installed.
15369 AndroidPackage pkg;
15372 String installerPackageName;
15373 PackageRemovedInfo removedInfo;
15374 ArrayMap<String, PackageInstalledInfo> addedChildPackages;
15375 // The set of packages consuming this shared library or null if no consumers exist.
15376 ArrayList<AndroidPackage> libraryConsumers;
15377 PackageFreezer freezer;
15379 public void setError(int code, String msg) {
15380 setReturnCode(code);
15381 setReturnMessage(msg);
15385 public void setError(String msg, PackageParserException e) {
15386 setReturnCode(e.error);
15387 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15388 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15389 for (int i = 0; i < childCount; i++) {
15390 addedChildPackages.valueAt(i).setError(msg, e);
15392 Slog.w(TAG, msg, e);
15395 public void setError(String msg, PackageManagerException e) {
15396 returnCode = e.error;
15397 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15398 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15399 for (int i = 0; i < childCount; i++) {
15400 addedChildPackages.valueAt(i).setError(msg, e);
15402 Slog.w(TAG, msg, e);
15405 public void setReturnCode(int returnCode) {
15406 this.returnCode = returnCode;
15407 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15408 for (int i = 0; i < childCount; i++) {
15409 addedChildPackages.valueAt(i).returnCode = returnCode;
15413 private void setReturnMessage(String returnMsg) {
15414 this.returnMsg = returnMsg;
15415 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15416 for (int i = 0; i < childCount; i++) {
15417 addedChildPackages.valueAt(i).returnMsg = returnMsg;
15421 // In some error cases we want to convey more info back to the observer
15422 String origPackage;
15423 String origPermission;
15426 private static void updateDigest(MessageDigest digest, File file) throws IOException {
15427 try (DigestInputStream digestStream =
15428 new DigestInputStream(new FileInputStream(file), digest)) {
15429 while (digestStream.read() != -1) {} // nothing to do; just plow through the file
15433 private void removeNativeBinariesLI(PackageSetting ps) {
15435 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
15439 @GuardedBy("mLock")
15440 private void enableSystemPackageLPw(AndroidPackage pkg) {
15441 mSettings.enableSystemPackageLPw(pkg.getPackageName());
15444 @GuardedBy("mLock")
15445 private boolean disableSystemPackageLPw(AndroidPackage oldPkg) {
15446 return mSettings.disableSystemPackageLPw(oldPkg.getPackageName(), true);
15449 private void updateSettingsLI(AndroidPackage newPackage, InstallArgs installArgs,
15450 int[] allUsers, PackageInstalledInfo res) {
15451 updateSettingsInternalLI(newPackage, installArgs, allUsers, res);
15454 private void updateSettingsInternalLI(AndroidPackage pkg, InstallArgs installArgs,
15455 int[] allUsers, PackageInstalledInfo res) {
15456 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
15458 final String pkgName = pkg.getPackageName();
15459 final int[] installedForUsers = res.origUsers;
15460 final int installReason = installArgs.installReason;
15461 InstallSource installSource = installArgs.installSource;
15462 final String installerPackageName = installSource.installerPackageName;
15464 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.getCodePath());
15465 synchronized (mLock) {
15466 // NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
15467 mPermissionManager.updatePermissions(pkgName, pkg);
15468 // For system-bundled packages, we assume that installing an upgraded version
15469 // of the package implies that the user actually wants to run that new code,
15470 // so we enable the package.
15471 final PackageSetting ps = mSettings.mPackages.get(pkgName);
15472 final int userId = installArgs.user.getIdentifier();
15474 if (pkg.isSystem()) {
15475 if (DEBUG_INSTALL) {
15476 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
15478 // Enable system package for requested users
15479 if (res.origUsers != null) {
15480 for (int origUserId : res.origUsers) {
15481 if (userId == UserHandle.USER_ALL || userId == origUserId) {
15482 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
15483 origUserId, installerPackageName);
15487 // Also convey the prior install/uninstall state
15488 if (allUsers != null && installedForUsers != null) {
15489 for (int currentUserId : allUsers) {
15490 final boolean installed = ArrayUtils.contains(
15491 installedForUsers, currentUserId);
15492 if (DEBUG_INSTALL) {
15493 Slog.d(TAG, " user " + currentUserId + " => " + installed);
15495 ps.setInstalled(installed, currentUserId);
15497 // these install state changes will be persisted in the
15498 // upcoming call to mSettings.writeLPr().
15502 // Retrieve the overlays for shared libraries of the package.
15503 if (!ps.getPkgState().getUsesLibraryInfos().isEmpty()) {
15504 for (SharedLibraryInfo sharedLib : ps.getPkgState().getUsesLibraryInfos()) {
15505 for (int currentUserId : UserManagerService.getInstance().getUserIds()) {
15506 if (!sharedLib.isDynamic()) {
15507 // TODO(146804378): Support overlaying static shared libraries
15510 final PackageSetting libPs = mSettings.mPackages.get(
15511 sharedLib.getPackageName());
15512 if (libPs == null) {
15515 final String[] overlayPaths = libPs.getOverlayPaths(currentUserId);
15516 if (overlayPaths != null) {
15517 ps.setOverlayPathsForLibrary(sharedLib.getName(),
15518 Arrays.asList(overlayPaths), currentUserId);
15524 // It's implied that when a user requests installation, they want the app to be
15525 // installed and enabled.
15526 if (userId != UserHandle.USER_ALL) {
15527 ps.setInstalled(true, userId);
15528 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
15531 if (installSource.initiatingPackageName != null) {
15532 final PackageSetting ips = mSettings.mPackages.get(
15533 installSource.initiatingPackageName);
15535 installSource = installSource.setInitiatingPackageSignatures(
15539 ps.setInstallSource(installSource);
15540 mSettings.addInstallerPackageNames(installSource);
15542 // When replacing an existing package, preserve the original install reason for all
15543 // users that had the package installed before.
15544 final Set<Integer> previousUserIds = new ArraySet<>();
15545 if (res.removedInfo != null && res.removedInfo.installReasons != null) {
15546 final int installReasonCount = res.removedInfo.installReasons.size();
15547 for (int i = 0; i < installReasonCount; i++) {
15548 final int previousUserId = res.removedInfo.installReasons.keyAt(i);
15549 final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
15550 ps.setInstallReason(previousInstallReason, previousUserId);
15551 previousUserIds.add(previousUserId);
15555 // Set install reason for users that are having the package newly installed.
15556 if (userId == UserHandle.USER_ALL) {
15557 for (int currentUserId : mUserManager.getUserIds()) {
15558 if (!previousUserIds.contains(currentUserId)) {
15559 ps.setInstallReason(installReason, currentUserId);
15562 } else if (!previousUserIds.contains(userId)) {
15563 ps.setInstallReason(installReason, userId);
15565 mSettings.writeKernelMappingLPr(ps);
15567 res.name = pkgName;
15568 res.uid = pkg.getUid();
15570 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
15571 //to update install status
15572 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
15573 mSettings.writeLPr();
15574 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15577 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15580 private static class InstallRequest {
15581 public final InstallArgs args;
15582 public final PackageInstalledInfo installResult;
15584 private InstallRequest(InstallArgs args, PackageInstalledInfo res) {
15586 this.installResult = res;
15590 @GuardedBy({"mInstallLock", "mLock"})
15591 private void installPackagesTracedLI(List<InstallRequest> requests) {
15593 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages");
15594 installPackagesLI(requests);
15596 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15601 * Package state to commit to memory and disk after reconciliation has completed.
15603 private static class CommitRequest {
15604 final Map<String, ReconciledPackage> reconciledPackages;
15605 final int[] mAllUsers;
15607 private CommitRequest(Map<String, ReconciledPackage> reconciledPackages, int[] allUsers) {
15608 this.reconciledPackages = reconciledPackages;
15609 this.mAllUsers = allUsers;
15614 * Package scan results and related request details used to reconcile the potential addition of
15615 * one or more packages to the system.
15617 * Reconcile will take a set of package details that need to be committed to the system and make
15618 * sure that they are valid in the context of the system and the other installing apps. Any
15619 * invalid state or app will result in a failed reconciliation and thus whatever operation (such
15620 * as install) led to the request.
15622 private static class ReconcileRequest {
15623 public final Map<String, ScanResult> scannedPackages;
15625 public final Map<String, AndroidPackage> allPackages;
15626 public final Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource;
15627 public final Map<String, InstallArgs> installArgs;
15628 public final Map<String, PackageInstalledInfo> installResults;
15629 public final Map<String, PrepareResult> preparedPackages;
15630 public final Map<String, VersionInfo> versionInfos;
15631 public final Map<String, PackageSetting> lastStaticSharedLibSettings;
15633 private ReconcileRequest(Map<String, ScanResult> scannedPackages,
15634 Map<String, InstallArgs> installArgs,
15635 Map<String, PackageInstalledInfo> installResults,
15636 Map<String, PrepareResult> preparedPackages,
15637 Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource,
15638 Map<String, AndroidPackage> allPackages,
15639 Map<String, VersionInfo> versionInfos,
15640 Map<String, PackageSetting> lastStaticSharedLibSettings) {
15641 this.scannedPackages = scannedPackages;
15642 this.installArgs = installArgs;
15643 this.installResults = installResults;
15644 this.preparedPackages = preparedPackages;
15645 this.sharedLibrarySource = sharedLibrarySource;
15646 this.allPackages = allPackages;
15647 this.versionInfos = versionInfos;
15648 this.lastStaticSharedLibSettings = lastStaticSharedLibSettings;
15651 private ReconcileRequest(Map<String, ScanResult> scannedPackages,
15652 Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource,
15653 Map<String, AndroidPackage> allPackages,
15654 Map<String, VersionInfo> versionInfos,
15655 Map<String, PackageSetting> lastStaticSharedLibSettings) {
15656 this(scannedPackages, Collections.emptyMap(), Collections.emptyMap(),
15657 Collections.emptyMap(), sharedLibrarySource, allPackages, versionInfos,
15658 lastStaticSharedLibSettings);
15661 private static class ReconcileFailure extends PackageManagerException {
15662 ReconcileFailure(String message) {
15663 super("Reconcile failed: " + message);
15665 ReconcileFailure(int reason, String message) {
15666 super(reason, "Reconcile failed: " + message);
15668 ReconcileFailure(PackageManagerException e) {
15669 this(e.error, e.getMessage());
15674 * A container of all data needed to commit a package to in-memory data structures and to disk.
15675 * TODO: move most of the data contained her into a PackageSetting for commit.
15677 private static class ReconciledPackage {
15678 public final ReconcileRequest request;
15679 public final PackageSetting pkgSetting;
15680 public final ScanResult scanResult;
15681 // TODO: Remove install-specific details from the reconcile result
15682 public final PackageInstalledInfo installResult;
15683 @Nullable public final PrepareResult prepareResult;
15684 @Nullable public final InstallArgs installArgs;
15685 public final DeletePackageAction deletePackageAction;
15686 public final List<SharedLibraryInfo> allowedSharedLibraryInfos;
15687 public final SigningDetails signingDetails;
15688 public final boolean sharedUserSignaturesChanged;
15689 public ArrayList<SharedLibraryInfo> collectedSharedLibraryInfos;
15690 public final boolean removeAppKeySetData;
15692 private ReconciledPackage(ReconcileRequest request,
15693 InstallArgs installArgs,
15694 PackageSetting pkgSetting,
15695 PackageInstalledInfo installResult,
15696 PrepareResult prepareResult,
15697 ScanResult scanResult,
15698 DeletePackageAction deletePackageAction,
15699 List<SharedLibraryInfo> allowedSharedLibraryInfos,
15700 SigningDetails signingDetails,
15701 boolean sharedUserSignaturesChanged,
15702 boolean removeAppKeySetData) {
15703 this.request = request;
15704 this.installArgs = installArgs;
15705 this.pkgSetting = pkgSetting;
15706 this.installResult = installResult;
15707 this.prepareResult = prepareResult;
15708 this.scanResult = scanResult;
15709 this.deletePackageAction = deletePackageAction;
15710 this.allowedSharedLibraryInfos = allowedSharedLibraryInfos;
15711 this.signingDetails = signingDetails;
15712 this.sharedUserSignaturesChanged = sharedUserSignaturesChanged;
15713 this.removeAppKeySetData = removeAppKeySetData;
15717 * Returns a combined set of packages containing the packages already installed combined
15718 * with the package(s) currently being installed. The to-be installed packages take
15719 * precedence and may shadow already installed packages.
15721 private Map<String, AndroidPackage> getCombinedAvailablePackages() {
15722 final ArrayMap<String, AndroidPackage> combined =
15723 new ArrayMap<>(request.allPackages.size() + request.scannedPackages.size());
15725 combined.putAll(request.allPackages);
15727 for (ScanResult scanResult : request.scannedPackages.values()) {
15728 combined.put(scanResult.pkgSetting.name, scanResult.request.parsedPackage);
15735 @GuardedBy("mLock")
15736 private static Map<String, ReconciledPackage> reconcilePackagesLocked(
15737 final ReconcileRequest request, KeySetManagerService ksms)
15738 throws ReconcileFailure {
15739 final Map<String, ScanResult> scannedPackages = request.scannedPackages;
15741 final Map<String, ReconciledPackage> result = new ArrayMap<>(scannedPackages.size());
15743 // make a copy of the existing set of packages so we can combine them with incoming packages
15744 final ArrayMap<String, AndroidPackage> combinedPackages =
15745 new ArrayMap<>(request.allPackages.size() + scannedPackages.size());
15747 combinedPackages.putAll(request.allPackages);
15749 final Map<String, LongSparseArray<SharedLibraryInfo>> incomingSharedLibraries =
15752 for (String installPackageName : scannedPackages.keySet()) {
15753 final ScanResult scanResult = scannedPackages.get(installPackageName);
15755 // add / replace existing with incoming packages
15756 combinedPackages.put(scanResult.pkgSetting.name, scanResult.request.parsedPackage);
15758 // in the first pass, we'll build up the set of incoming shared libraries
15759 final List<SharedLibraryInfo> allowedSharedLibInfos =
15760 getAllowedSharedLibInfos(scanResult, request.sharedLibrarySource);
15761 final SharedLibraryInfo staticLib = scanResult.staticSharedLibraryInfo;
15762 if (allowedSharedLibInfos != null) {
15763 for (SharedLibraryInfo info : allowedSharedLibInfos) {
15764 if (!addSharedLibraryToPackageVersionMap(incomingSharedLibraries, info)) {
15765 throw new ReconcileFailure("Static Shared Library " + staticLib.getName()
15766 + " is being installed twice in this set!");
15771 // the following may be null if we're just reconciling on boot (and not during install)
15772 final InstallArgs installArgs = request.installArgs.get(installPackageName);
15773 final PackageInstalledInfo res = request.installResults.get(installPackageName);
15774 final PrepareResult prepareResult = request.preparedPackages.get(installPackageName);
15775 final boolean isInstall = installArgs != null;
15776 if (isInstall && (res == null || prepareResult == null)) {
15777 throw new ReconcileFailure("Reconcile arguments are not balanced for "
15778 + installPackageName + "!");
15781 final DeletePackageAction deletePackageAction;
15782 // we only want to try to delete for non system apps
15783 if (isInstall && prepareResult.replace && !prepareResult.system) {
15784 final boolean killApp = (scanResult.request.scanFlags & SCAN_DONT_KILL_APP) == 0;
15785 final int deleteFlags = PackageManager.DELETE_KEEP_DATA
15786 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
15787 deletePackageAction = mayDeletePackageLocked(res.removedInfo,
15788 prepareResult.originalPs, prepareResult.disabledPs,
15789 deleteFlags, null /* all users */);
15790 if (deletePackageAction == null) {
15791 throw new ReconcileFailure(
15792 PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE,
15793 "May not delete " + installPackageName + " to replace");
15796 deletePackageAction = null;
15799 final int scanFlags = scanResult.request.scanFlags;
15800 final int parseFlags = scanResult.request.parseFlags;
15801 final ParsedPackage parsedPackage = scanResult.request.parsedPackage;
15803 final PackageSetting disabledPkgSetting = scanResult.request.disabledPkgSetting;
15804 final PackageSetting lastStaticSharedLibSetting =
15805 request.lastStaticSharedLibSettings.get(installPackageName);
15806 final PackageSetting signatureCheckPs =
15807 (prepareResult != null && lastStaticSharedLibSetting != null)
15808 ? lastStaticSharedLibSetting
15809 : scanResult.pkgSetting;
15810 boolean removeAppKeySetData = false;
15811 boolean sharedUserSignaturesChanged = false;
15812 SigningDetails signingDetails = null;
15813 if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
15814 if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
15815 // We just determined the app is signed correctly, so bring
15816 // over the latest parsed certs.
15818 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
15819 throw new ReconcileFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15820 "Package " + parsedPackage.getPackageName()
15821 + " upgrade keys do not match the previously installed"
15824 String msg = "System package " + parsedPackage.getPackageName()
15825 + " signature changed; retaining data.";
15826 reportSettingsProblem(Log.WARN, msg);
15829 signingDetails = parsedPackage.getSigningDetails();
15832 final VersionInfo versionInfo = request.versionInfos.get(installPackageName);
15833 final boolean compareCompat = isCompatSignatureUpdateNeeded(versionInfo);
15834 final boolean compareRecover = isRecoverSignatureUpdateNeeded(versionInfo);
15835 final boolean compatMatch = verifySignatures(signatureCheckPs,
15836 disabledPkgSetting, parsedPackage.getSigningDetails(), compareCompat,
15838 // The new KeySets will be re-added later in the scanning process.
15840 removeAppKeySetData = true;
15842 // We just determined the app is signed correctly, so bring
15843 // over the latest parsed certs.
15844 signingDetails = parsedPackage.getSigningDetails();
15847 // if this is is a sharedUser, check to see if the new package is signed by a
15849 // signing certificate than the existing one, and if so, copy over the new
15851 if (signatureCheckPs.sharedUser != null) {
15852 if (parsedPackage.getSigningDetails().hasAncestor(
15853 signatureCheckPs.sharedUser.signatures.mSigningDetails)) {
15854 signatureCheckPs.sharedUser.signatures.mSigningDetails =
15855 parsedPackage.getSigningDetails();
15857 if (signatureCheckPs.sharedUser.signaturesChanged == null) {
15858 signatureCheckPs.sharedUser.signaturesChanged = Boolean.FALSE;
15861 } catch (PackageManagerException e) {
15862 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
15863 throw new ReconcileFailure(e);
15865 signingDetails = parsedPackage.getSigningDetails();
15867 // If the system app is part of a shared user we allow that shared user to
15869 // signatures as well as part of an OTA. We still need to verify that the
15871 // are consistent within the shared user for a given boot, so only allow
15873 // the signatures on the first package scanned for the shared user (i.e. if the
15874 // signaturesChanged state hasn't been initialized yet in SharedUserSetting).
15875 if (signatureCheckPs.sharedUser != null) {
15876 final Signature[] sharedUserSignatures =
15877 signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures;
15878 if (signatureCheckPs.sharedUser.signaturesChanged != null
15879 && compareSignatures(sharedUserSignatures,
15880 parsedPackage.getSigningDetails().signatures)
15881 != PackageManager.SIGNATURE_MATCH) {
15882 if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 29) {
15883 // Mismatched signatures is an error and silently skipping system
15884 // packages will likely break the device in unforeseen ways.
15885 // However, we allow the device to boot anyway because, prior to Q,
15886 // vendors were not expecting the platform to crash in this
15888 // This WILL be a hard failure on any new API levels after Q.
15889 throw new ReconcileFailure(
15890 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
15891 "Signature mismatch for shared user: "
15892 + scanResult.pkgSetting.sharedUser);
15894 // Treat mismatched signatures on system packages using a shared
15896 // fatal for the system overall, rather than just failing to install
15897 // whichever package happened to be scanned later.
15898 throw new IllegalStateException(
15899 "Signature mismatch on system package "
15900 + parsedPackage.getPackageName()
15901 + " for shared user "
15902 + scanResult.pkgSetting.sharedUser);
15906 sharedUserSignaturesChanged = true;
15907 signatureCheckPs.sharedUser.signatures.mSigningDetails =
15908 parsedPackage.getSigningDetails();
15909 signatureCheckPs.sharedUser.signaturesChanged = Boolean.TRUE;
15911 // File a report about this.
15912 String msg = "System package " + parsedPackage.getPackageName()
15913 + " signature changed; retaining data.";
15914 reportSettingsProblem(Log.WARN, msg);
15915 } catch (IllegalArgumentException e) {
15916 // should never happen: certs matched when checking, but not when comparing
15917 // old to new for sharedUser
15918 throw new RuntimeException(
15919 "Signing certificates comparison made on incomparable signing details"
15920 + " but somehow passed verifySignatures!", e);
15924 result.put(installPackageName,
15925 new ReconciledPackage(request, installArgs, scanResult.pkgSetting,
15926 res, request.preparedPackages.get(installPackageName), scanResult,
15927 deletePackageAction, allowedSharedLibInfos, signingDetails,
15928 sharedUserSignaturesChanged, removeAppKeySetData));
15931 for (String installPackageName : scannedPackages.keySet()) {
15932 // Check all shared libraries and map to their actual file path.
15933 // We only do this here for apps not on a system dir, because those
15934 // are the only ones that can fail an install due to this. We
15935 // will take care of the system apps by updating all of their
15936 // library paths after the scan is done. Also during the initial
15937 // scan don't update any libs as we do this wholesale after all
15938 // apps are scanned to avoid dependency based scanning.
15939 final ScanResult scanResult = scannedPackages.get(installPackageName);
15940 if ((scanResult.request.scanFlags & SCAN_BOOTING) != 0
15941 || (scanResult.request.parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
15945 result.get(installPackageName).collectedSharedLibraryInfos =
15946 collectSharedLibraryInfos(scanResult.request.parsedPackage,
15947 combinedPackages, request.sharedLibrarySource,
15948 incomingSharedLibraries);
15950 } catch (PackageManagerException e) {
15951 throw new ReconcileFailure(e.error, e.getMessage());
15959 * Compare the newly scanned package with current system state to see which of its declared
15960 * shared libraries should be allowed to be added to the system.
15962 private static List<SharedLibraryInfo> getAllowedSharedLibInfos(
15963 ScanResult scanResult,
15964 Map<String, LongSparseArray<SharedLibraryInfo>> existingSharedLibraries) {
15965 // Let's used the parsed package as scanResult.pkgSetting may be null
15966 final ParsedPackage parsedPackage = scanResult.request.parsedPackage;
15967 if (scanResult.staticSharedLibraryInfo == null
15968 && scanResult.dynamicSharedLibraryInfos == null) {
15972 // Any app can add new static shared libraries
15973 if (scanResult.staticSharedLibraryInfo != null) {
15974 return Collections.singletonList(scanResult.staticSharedLibraryInfo);
15976 final boolean hasDynamicLibraries = parsedPackage.isSystem()
15977 && scanResult.dynamicSharedLibraryInfos != null;
15978 if (!hasDynamicLibraries) {
15981 final boolean isUpdatedSystemApp = scanResult.pkgSetting.getPkgState()
15982 .isUpdatedSystemApp();
15983 // We may not yet have disabled the updated package yet, so be sure to grab the
15984 // current setting if that's the case.
15985 final PackageSetting updatedSystemPs = isUpdatedSystemApp
15986 ? scanResult.request.disabledPkgSetting == null
15987 ? scanResult.request.oldPkgSetting
15988 : scanResult.request.disabledPkgSetting
15990 if (isUpdatedSystemApp && (updatedSystemPs.pkg == null
15991 || updatedSystemPs.pkg.getLibraryNames() == null)) {
15992 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
15993 + " declares libraries that are not declared on the system image; skipping");
15996 final ArrayList<SharedLibraryInfo> infos =
15997 new ArrayList<>(scanResult.dynamicSharedLibraryInfos.size());
15998 for (SharedLibraryInfo info : scanResult.dynamicSharedLibraryInfos) {
15999 final String name = info.getName();
16000 if (isUpdatedSystemApp) {
16001 // New library entries can only be added through the
16002 // system image. This is important to get rid of a lot
16003 // of nasty edge cases: for example if we allowed a non-
16004 // system update of the app to add a library, then uninstalling
16005 // the update would make the library go away, and assumptions
16006 // we made such as through app install filtering would now
16007 // have allowed apps on the device which aren't compatible
16008 // with it. Better to just have the restriction here, be
16009 // conservative, and create many fewer cases that can negatively
16010 // impact the user experience.
16011 if (!updatedSystemPs.pkg.getLibraryNames().contains(name)) {
16012 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
16013 + " declares library " + name
16014 + " that is not declared on system image; skipping");
16018 if (sharedLibExists(
16019 name, SharedLibraryInfo.VERSION_UNDEFINED, existingSharedLibraries)) {
16020 Slog.w(TAG, "Package " + parsedPackage.getPackageName() + " declares library "
16021 + name + " that already exists; skipping");
16030 * Returns false if the adding shared library already exists in the map and so could not be
16033 private static boolean addSharedLibraryToPackageVersionMap(
16034 Map<String, LongSparseArray<SharedLibraryInfo>> target,
16035 SharedLibraryInfo library) {
16036 final String name = library.getName();
16037 if (target.containsKey(name)) {
16038 if (library.getType() != SharedLibraryInfo.TYPE_STATIC) {
16039 // We've already added this non-version-specific library to the map.
16041 } else if (target.get(name).indexOfKey(library.getLongVersion()) >= 0) {
16042 // We've already added this version of a version-specific library to the map.
16046 target.put(name, new LongSparseArray<>());
16048 target.get(name).put(library.getLongVersion(), library);
16052 @GuardedBy("mLock")
16053 private void commitPackagesLocked(final CommitRequest request) {
16054 // TODO: remove any expected failures from this method; this should only be able to fail due
16055 // to unavoidable errors (I/O, etc.)
16056 for (ReconciledPackage reconciledPkg : request.reconciledPackages.values()) {
16057 final ScanResult scanResult = reconciledPkg.scanResult;
16058 final ScanRequest scanRequest = scanResult.request;
16059 final ParsedPackage parsedPackage = scanRequest.parsedPackage;
16060 final String packageName = parsedPackage.getPackageName();
16061 final PackageInstalledInfo res = reconciledPkg.installResult;
16063 if (reconciledPkg.prepareResult.replace) {
16064 AndroidPackage oldPackage = mPackages.get(packageName);
16066 // Set the update and install times
16067 PackageSetting deletedPkgSetting = getPackageSetting(oldPackage.getPackageName());
16068 reconciledPkg.pkgSetting.firstInstallTime = deletedPkgSetting.firstInstallTime;
16069 reconciledPkg.pkgSetting.lastUpdateTime = System.currentTimeMillis();
16071 if (reconciledPkg.prepareResult.system) {
16072 // Remove existing system package
16073 removePackageLI(oldPackage, true);
16074 if (!disableSystemPackageLPw(oldPackage)) {
16075 // We didn't need to disable the .apk as a current system package,
16076 // which means we are replacing another update that is already
16077 // installed. We need to make sure to delete the older one's .apk.
16078 res.removedInfo.args = createInstallArgsForExisting(
16079 oldPackage.getCodePath(),
16080 oldPackage.getCodePath(),
16081 getAppDexInstructionSets(
16082 AndroidPackageUtils.getPrimaryCpuAbi(oldPackage,
16083 deletedPkgSetting),
16084 AndroidPackageUtils.getSecondaryCpuAbi(oldPackage,
16085 deletedPkgSetting)));
16087 res.removedInfo.args = null;
16091 // Settings will be written during the call to updateSettingsLI().
16092 executeDeletePackageLIF(reconciledPkg.deletePackageAction, packageName,
16093 true, request.mAllUsers, false, parsedPackage);
16094 } catch (SystemDeleteException e) {
16095 if (Build.IS_ENG) {
16096 throw new RuntimeException("Unexpected failure", e);
16097 // ignore; not possible for non-system app
16100 // Successfully deleted the old package; proceed with replace.
16102 // If deleted package lived in a container, give users a chance to
16103 // relinquish resources before killing.
16104 if (oldPackage.isExternalStorage()) {
16105 if (DEBUG_INSTALL) {
16106 Slog.i(TAG, "upgrading pkg " + oldPackage
16107 + " is ASEC-hosted -> UNAVAILABLE");
16109 final int[] uidArray = new int[]{oldPackage.getUid()};
16110 final ArrayList<String> pkgList = new ArrayList<>(1);
16111 pkgList.add(oldPackage.getPackageName());
16112 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16115 // Update the in-memory copy of the previous code paths.
16116 PackageSetting ps1 = mSettings.mPackages.get(
16117 reconciledPkg.prepareResult.existingPackage.getPackageName());
16118 if ((reconciledPkg.installArgs.installFlags & PackageManager.DONT_KILL_APP)
16120 if (ps1.mOldCodePaths == null) {
16121 ps1.mOldCodePaths = new ArraySet<>();
16123 Collections.addAll(ps1.mOldCodePaths, oldPackage.getBaseCodePath());
16124 if (oldPackage.getSplitCodePaths() != null) {
16125 Collections.addAll(ps1.mOldCodePaths, oldPackage.getSplitCodePaths());
16128 ps1.mOldCodePaths = null;
16131 if (reconciledPkg.installResult.returnCode
16132 == PackageManager.INSTALL_SUCCEEDED) {
16133 PackageSetting ps2 = mSettings.getPackageLPr(
16134 parsedPackage.getPackageName());
16136 res.removedInfo.removedForAllUsers = mPackages.get(ps2.name) == null;
16142 AndroidPackage pkg = commitReconciledScanResultLocked(reconciledPkg);
16143 updateSettingsLI(pkg, reconciledPkg.installArgs, request.mAllUsers, res);
16145 final PackageSetting ps = mSettings.mPackages.get(packageName);
16147 res.newUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
16148 ps.setUpdateAvailable(false /*updateAvailable*/);
16150 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16151 updateSequenceNumberLP(ps, res.newUsers);
16152 updateInstantAppInstallerLocked(packageName);
16158 * Installs one or more packages atomically. This operation is broken up into four phases:
16160 * <li><b>Prepare</b>
16161 * <br/>Analyzes any current install state, parses the package and does initial
16162 * validation on it.</li>
16164 * <br/>Interrogates the parsed packages given the context collected in prepare.</li>
16165 * <li><b>Reconcile</b>
16166 * <br/>Validates scanned packages in the context of each other and the current system
16167 * state to ensure that the install will be successful.
16168 * <li><b>Commit</b>
16169 * <br/>Commits all scanned packages and updates system state. This is the only place
16170 * that system state may be modified in the install flow and all predictable errors
16171 * must be determined before this phase.</li>
16174 * Failure at any phase will result in a full failure to install all packages.
16176 @GuardedBy("mInstallLock")
16177 private void installPackagesLI(List<InstallRequest> requests) {
16178 final Map<String, ScanResult> preparedScans = new ArrayMap<>(requests.size());
16179 final Map<String, InstallArgs> installArgs = new ArrayMap<>(requests.size());
16180 final Map<String, PackageInstalledInfo> installResults = new ArrayMap<>(requests.size());
16181 final Map<String, PrepareResult> prepareResults = new ArrayMap<>(requests.size());
16182 final Map<String, VersionInfo> versionInfos = new ArrayMap<>(requests.size());
16183 final Map<String, PackageSetting> lastStaticSharedLibSettings =
16184 new ArrayMap<>(requests.size());
16185 final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size());
16186 boolean success = false;
16188 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackagesLI");
16189 for (InstallRequest request : requests) {
16190 // TODO(b/109941548): remove this once we've pulled everything from it and into
16191 // scan, reconcile or commit.
16192 final PrepareResult prepareResult;
16194 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage");
16196 preparePackageLI(request.args, request.installResult);
16197 } catch (PrepareFailure prepareFailure) {
16198 request.installResult.setError(prepareFailure.error,
16199 prepareFailure.getMessage());
16200 request.installResult.origPackage = prepareFailure.conflictingPackage;
16201 request.installResult.origPermission = prepareFailure.conflictingPermission;
16204 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16206 request.installResult.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16207 request.installResult.installerPackageName =
16208 request.args.installSource.installerPackageName;
16210 final String packageName = prepareResult.packageToScan.getPackageName();
16211 prepareResults.put(packageName, prepareResult);
16212 installResults.put(packageName, request.installResult);
16213 installArgs.put(packageName, request.args);
16215 final ScanResult result = scanPackageTracedLI(
16216 prepareResult.packageToScan, prepareResult.parseFlags,
16217 prepareResult.scanFlags, System.currentTimeMillis(),
16218 request.args.user, request.args.abiOverride);
16219 if (null != preparedScans.put(result.pkgSetting.pkg.getPackageName(), result)) {
16220 request.installResult.setError(
16221 PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE,
16222 "Duplicate package " + result.pkgSetting.pkg.getPackageName()
16223 + " in multi-package install request.");
16226 createdAppId.put(packageName, optimisticallyRegisterAppId(result));
16227 versionInfos.put(result.pkgSetting.pkg.getPackageName(),
16228 getSettingsVersionForPackage(result.pkgSetting.pkg));
16229 if (result.staticSharedLibraryInfo != null) {
16230 final PackageSetting sharedLibLatestVersionSetting =
16231 getSharedLibLatestVersionSetting(result);
16232 if (sharedLibLatestVersionSetting != null) {
16233 lastStaticSharedLibSettings.put(result.pkgSetting.pkg.getPackageName(),
16234 sharedLibLatestVersionSetting);
16237 } catch (PackageManagerException e) {
16238 request.installResult.setError("Scanning Failed.", e);
16242 ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs,
16246 Collections.unmodifiableMap(mPackages), versionInfos,
16247 lastStaticSharedLibSettings);
16248 CommitRequest commitRequest = null;
16249 synchronized (mLock) {
16250 Map<String, ReconciledPackage> reconciledPackages;
16252 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages");
16253 reconciledPackages = reconcilePackagesLocked(
16254 reconcileRequest, mSettings.mKeySetManagerService);
16255 } catch (ReconcileFailure e) {
16256 for (InstallRequest request : requests) {
16257 request.installResult.setError("Reconciliation failed...", e);
16261 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16264 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "commitPackages");
16265 commitRequest = new CommitRequest(reconciledPackages,
16266 mUserManager.getUserIds());
16267 commitPackagesLocked(commitRequest);
16270 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16273 executePostCommitSteps(commitRequest);
16276 for (ScanResult result : preparedScans.values()) {
16277 if (createdAppId.getOrDefault(result.request.parsedPackage.getPackageName(),
16279 cleanUpAppIdCreation(result);
16282 // TODO(patb): create a more descriptive reason than unknown in future release
16283 // mark all non-failure installs as UNKNOWN so we do not treat them as success
16284 for (InstallRequest request : requests) {
16285 if (request.installResult.freezer != null) {
16286 request.installResult.freezer.close();
16288 if (request.installResult.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16289 request.installResult.returnCode = PackageManager.INSTALL_UNKNOWN;
16293 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16298 * On successful install, executes remaining steps after commit completes and the package lock
16299 * is released. These are typically more expensive or require calls to installd, which often
16300 * locks on {@link #mLock}.
16302 private void executePostCommitSteps(CommitRequest commitRequest) {
16303 for (ReconciledPackage reconciledPkg : commitRequest.reconciledPackages.values()) {
16304 final boolean instantApp = ((reconciledPkg.scanResult.request.scanFlags
16305 & PackageManagerService.SCAN_AS_INSTANT_APP) != 0);
16306 final AndroidPackage pkg = reconciledPkg.pkgSetting.pkg;
16307 final String packageName = pkg.getPackageName();
16308 final boolean onIncremental = mIncrementalManager != null
16309 && isIncrementalPath(pkg.getCodePath());
16310 prepareAppDataAfterInstallLIF(pkg);
16311 if (reconciledPkg.prepareResult.clearCodeCache) {
16312 clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
16313 | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16315 if (reconciledPkg.prepareResult.replace) {
16316 mDexManager.notifyPackageUpdated(pkg.getPackageName(),
16317 pkg.getBaseCodePath(), pkg.getSplitCodePaths());
16320 // Prepare the application profiles for the new code paths.
16321 // This needs to be done before invoking dexopt so that any install-time profile
16322 // can be used for optimizations.
16323 mArtManagerService.prepareAppProfiles(
16325 resolveUserIds(reconciledPkg.installArgs.user.getIdentifier()),
16326 /* updateReferenceProfileContent= */ true);
16328 // Check whether we need to dexopt the app.
16330 // NOTE: it is IMPORTANT to call dexopt:
16331 // - after doRename which will sync the package data from AndroidPackage and
16332 // its corresponding ApplicationInfo.
16333 // - after installNewPackageLIF or replacePackageLIF which will update result with the
16334 // uid of the application (pkg.applicationInfo.uid).
16335 // This update happens in place!
16337 // We only need to dexopt if the package meets ALL of the following conditions:
16338 // 1) it is not an instant app or if it is then dexopt is enabled via gservices.
16339 // 2) it is not debuggable.
16340 // 3) it is not on Incremental File System.
16342 // Note that we do not dexopt instant apps by default. dexopt can take some time to
16343 // complete, so we skip this step during installation. Instead, we'll take extra time
16344 // the first time the instant app starts. It's preferred to do it this way to provide
16345 // continuous progress to the useur instead of mysteriously blocking somewhere in the
16346 // middle of running an instant app. The default behaviour can be overridden
16348 final boolean performDexopt =
16349 (!instantApp || Global.getInt(mContext.getContentResolver(),
16350 Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
16351 && !pkg.isDebuggable()
16352 && (!onIncremental);
16354 if (performDexopt) {
16355 // Compile the layout resources.
16356 if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
16357 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "compileLayouts");
16358 mViewCompiler.compileLayouts(pkg);
16359 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16362 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
16363 // Do not run PackageDexOptimizer through the local performDexOpt
16364 // method because `pkg` may not be in `mPackages` yet.
16366 // Also, don't fail application installs if the dexopt step fails.
16367 DexoptOptions dexoptOptions = new DexoptOptions(packageName,
16369 DexoptOptions.DEXOPT_BOOT_COMPLETE
16370 | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE);
16371 ScanResult result = reconciledPkg.scanResult;
16373 // This mirrors logic from commitReconciledScanResultLocked, where the library files
16374 // needed for dexopt are assigned.
16375 // TODO: Fix this to have 1 mutable PackageSetting for scan/install. If the previous
16376 // setting needs to be passed to have a comparison, hide it behind an immutable
16377 // interface. There's no good reason to have 3 different ways to access the real
16378 // PackageSetting object, only one of which is actually correct.
16379 PackageSetting realPkgSetting = result.existingSettingCopied
16380 ? result.request.pkgSetting : result.pkgSetting;
16381 if (realPkgSetting == null) {
16382 realPkgSetting = reconciledPkg.pkgSetting;
16385 // Unfortunately, the updated system app flag is only tracked on this PackageSetting
16386 boolean isUpdatedSystemApp = reconciledPkg.pkgSetting.getPkgState()
16387 .isUpdatedSystemApp();
16389 realPkgSetting.getPkgState().setUpdatedSystemApp(isUpdatedSystemApp);
16391 mPackageDexOptimizer.performDexOpt(pkg, realPkgSetting,
16392 null /* instructionSets */,
16393 getOrCreateCompilerPackageStats(pkg),
16394 mDexManager.getPackageUseInfoOrDefault(packageName),
16396 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16399 // Notify BackgroundDexOptService that the package has been changed.
16400 // If this is an update of a package which used to fail to compile,
16401 // BackgroundDexOptService will remove it from its blacklist.
16402 // TODO: Layering violation
16403 BackgroundDexOptService.notifyPackageChanged(packageName);
16408 * The set of data needed to successfully install the prepared package. This includes data that
16409 * will be used to scan and reconcile the package.
16411 private static class PrepareResult {
16412 public final boolean replace;
16413 public final int scanFlags;
16414 public final int parseFlags;
16415 @Nullable /* The original Package if it is being replaced, otherwise {@code null} */
16416 public final AndroidPackage existingPackage;
16417 public final ParsedPackage packageToScan;
16418 public final boolean clearCodeCache;
16419 public final boolean system;
16420 public final PackageSetting originalPs;
16421 public final PackageSetting disabledPs;
16423 private PrepareResult(boolean replace, int scanFlags,
16424 int parseFlags, AndroidPackage existingPackage,
16425 ParsedPackage packageToScan, boolean clearCodeCache, boolean system,
16426 PackageSetting originalPs, PackageSetting disabledPs) {
16427 this.replace = replace;
16428 this.scanFlags = scanFlags;
16429 this.parseFlags = parseFlags;
16430 this.existingPackage = existingPackage;
16431 this.packageToScan = packageToScan;
16432 this.clearCodeCache = clearCodeCache;
16433 this.system = system;
16434 this.originalPs = originalPs;
16435 this.disabledPs = disabledPs;
16439 private static class PrepareFailure extends PackageManagerException {
16441 public String conflictingPackage;
16442 public String conflictingPermission;
16444 PrepareFailure(int error) {
16445 super(error, "Failed to prepare for install.");
16448 PrepareFailure(int error, String detailMessage) {
16449 super(error, detailMessage);
16452 PrepareFailure(String message, Exception e) {
16453 super(e instanceof PackageParserException
16454 ? ((PackageParserException) e).error
16455 : ((PackageManagerException) e).error,
16456 ExceptionUtils.getCompleteMessage(message, e));
16459 PrepareFailure conflictsWithExistingPermission(String conflictingPermission,
16460 String conflictingPackage) {
16461 this.conflictingPermission = conflictingPermission;
16462 this.conflictingPackage = conflictingPackage;
16467 @GuardedBy("mInstallLock")
16468 private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res)
16469 throws PrepareFailure {
16470 final int installFlags = args.installFlags;
16471 final File tmpPackageFile = new File(args.getCodePath());
16472 final boolean onExternal = args.volumeUuid != null;
16473 final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
16474 final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
16475 final boolean virtualPreload =
16476 ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
16477 @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
16478 if (args.move != null) {
16479 // moving a complete application; perform an initial scan on the new install location
16480 scanFlags |= SCAN_INITIAL;
16482 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
16483 scanFlags |= SCAN_DONT_KILL_APP;
16486 scanFlags |= SCAN_AS_INSTANT_APP;
16489 scanFlags |= SCAN_AS_FULL_APP;
16491 if (virtualPreload) {
16492 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
16495 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
16498 if (instantApp && onExternal) {
16499 Slog.i(TAG, "Incompatible ephemeral install; external=" + onExternal);
16500 throw new PrepareFailure(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16503 // Retrieve PackageSettings and parse package
16504 @ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
16505 | PackageParser.PARSE_ENFORCE_CODE
16506 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16508 PackageParser2 pp = new PackageParser2(mSeparateProcesses, false, mMetrics, null,
16509 mPackageParserCallback);
16511 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
16512 ParsedPackage parsedPackage;
16514 parsedPackage = pp.parsePackage(tmpPackageFile, parseFlags, false);
16515 AndroidPackageUtils.validatePackageDexMetadata(parsedPackage);
16516 } catch (PackageParserException e) {
16517 throw new PrepareFailure("Failed parse during installPackageLI", e);
16519 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16522 // Instant apps have several additional install-time checks.
16524 if (parsedPackage.getTargetSdkVersion() < Build.VERSION_CODES.O) {
16525 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
16526 + " does not target at least O");
16527 throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
16528 "Instant app package must target at least O");
16530 if (parsedPackage.getSharedUserId() != null) {
16531 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
16532 + " may not declare sharedUserId.");
16533 throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
16534 "Instant app package may not declare a sharedUserId");
16538 if (parsedPackage.isStaticSharedLibrary()) {
16539 // Static shared libraries have synthetic package names
16540 renameStaticSharedLibraryPackage(parsedPackage);
16542 // No static shared libs on external storage
16544 Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
16545 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16546 "Packages declaring static-shared libs cannot be updated");
16550 String pkgName = res.name = parsedPackage.getPackageName();
16551 if (parsedPackage.isTestOnly()) {
16552 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
16553 throw new PrepareFailure(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
16558 // either use what we've been given or parse directly from the APK
16559 if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
16560 parsedPackage.setSigningDetails(args.signingDetails);
16562 // TODO(b/136132412): skip for Incremental installation
16563 parsedPackage.setSigningDetails(
16564 ParsingPackageUtils.collectCertificates(parsedPackage, false /* skipVerify */));
16566 } catch (PackageParserException e) {
16567 throw new PrepareFailure("Failed collect during installPackageLI", e);
16570 if (instantApp && parsedPackage.getSigningDetails().signatureSchemeVersion
16571 < SignatureSchemeVersion.SIGNING_BLOCK_V2) {
16572 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
16573 + " is not signed with at least APK Signature Scheme v2");
16574 throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
16575 "Instant app package must be signed with APK Signature Scheme v2 or greater");
16578 // Get rid of all references to package scan path via parser.
16580 boolean systemApp = false;
16581 boolean replace = false;
16582 synchronized (mLock) {
16583 // Check if installing already existing package
16584 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16585 String oldName = mSettings.getRenamedPackageLPr(pkgName);
16586 if (parsedPackage.getOriginalPackages().contains(oldName)
16587 && mPackages.containsKey(oldName)) {
16588 // This package is derived from an original package,
16589 // and this device has been updating from that original
16590 // name. We must continue using the original name, so
16591 // rename the new package here.
16592 parsedPackage.setPackageName(oldName);
16593 pkgName = parsedPackage.getPackageName();
16595 if (DEBUG_INSTALL) {
16596 Slog.d(TAG, "Replacing existing renamed package: oldName="
16597 + oldName + " pkgName=" + pkgName);
16599 } else if (mPackages.containsKey(pkgName)) {
16600 // This package, under its official name, already exists
16601 // on the device; we should replace it.
16603 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
16607 // Prevent apps opting out from runtime permissions
16608 AndroidPackage oldPackage = mPackages.get(pkgName);
16609 final int oldTargetSdk = oldPackage.getTargetSdkVersion();
16610 final int newTargetSdk = parsedPackage.getTargetSdkVersion();
16611 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
16612 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
16613 throw new PrepareFailure(
16614 PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
16615 "Package " + parsedPackage.getPackageName()
16616 + " new target SDK " + newTargetSdk
16617 + " doesn't support runtime permissions but the old"
16618 + " target SDK " + oldTargetSdk + " does.");
16620 // Prevent persistent apps from being updated
16621 if (oldPackage.isPersistent()
16622 && ((installFlags & PackageManager.INSTALL_STAGED) == 0)) {
16623 throw new PrepareFailure(PackageManager.INSTALL_FAILED_INVALID_APK,
16624 "Package " + oldPackage.getPackageName() + " is a persistent app. "
16625 + "Persistent apps are not updateable.");
16630 PackageSetting ps = mSettings.mPackages.get(pkgName);
16632 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
16634 // Static shared libs have same package with different versions where
16635 // we internally use a synthetic package name to allow multiple versions
16636 // of the same package, therefore we need to compare signatures against
16637 // the package setting for the latest library version.
16638 PackageSetting signatureCheckPs = ps;
16639 if (parsedPackage.isStaticSharedLibrary()) {
16640 SharedLibraryInfo libraryInfo = getLatestSharedLibraVersionLPr(parsedPackage);
16641 if (libraryInfo != null) {
16642 signatureCheckPs = mSettings.getPackageLPr(libraryInfo.getPackageName());
16646 // Quick sanity check that we're signed correctly if updating;
16647 // we'll check this again later when scanning, but we want to
16648 // bail early here before tripping over redefined permissions.
16649 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16650 if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
16651 if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
16652 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
16653 + parsedPackage.getPackageName() + " upgrade keys do not match the "
16654 + "previously installed version");
16658 final boolean compareCompat = isCompatSignatureUpdateNeeded(parsedPackage);
16659 final boolean compareRecover = isRecoverSignatureUpdateNeeded(
16661 // We don't care about disabledPkgSetting on install for now.
16662 final boolean compatMatch = verifySignatures(signatureCheckPs, null,
16663 parsedPackage.getSigningDetails(), compareCompat, compareRecover);
16664 // The new KeySets will be re-added later in the scanning process.
16666 synchronized (mLock) {
16667 ksms.removeAppKeySetDataLPw(parsedPackage.getPackageName());
16670 } catch (PackageManagerException e) {
16671 throw new PrepareFailure(e.error, e.getMessage());
16675 if (ps.pkg != null) {
16676 systemApp = ps.pkg.isSystem();
16678 res.origUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
16682 int N = ArrayUtils.size(parsedPackage.getPermissions());
16683 for (int i = N - 1; i >= 0; i--) {
16684 final ParsedPermission perm = parsedPackage.getPermissions().get(i);
16685 final BasePermission bp = mPermissionManager.getPermissionTEMP(perm.getName());
16687 // Don't allow anyone but the system to define ephemeral permissions.
16688 if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
16690 Slog.w(TAG, "Non-System package " + parsedPackage.getPackageName()
16691 + " attempting to delcare ephemeral permission "
16692 + perm.getName() + "; Removing ephemeral.");
16693 perm.setProtectionLevel(perm.getProtectionLevel() & ~PermissionInfo.PROTECTION_FLAG_INSTANT);
16696 // Check whether the newly-scanned package wants to define an already-defined perm
16698 // If the defining package is signed with our cert, it's okay. This
16699 // also includes the "updating the same package" case, of course.
16700 // "updating same package" could also involve key-rotation.
16701 final boolean sigsOk;
16702 final String sourcePackageName = bp.getSourcePackageName();
16703 final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
16704 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16705 if (sourcePackageName.equals(parsedPackage.getPackageName())
16706 && (ksms.shouldCheckUpgradeKeySetLocked(
16707 sourcePackageSetting, scanFlags))) {
16708 sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, parsedPackage);
16711 // in the event of signing certificate rotation, we need to see if the
16712 // package's certificate has rotated from the current one, or if it is an
16713 // older certificate with which the current is ok with sharing permissions
16714 if (sourcePackageSetting.signatures.mSigningDetails.checkCapability(
16715 parsedPackage.getSigningDetails(),
16716 PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
16718 } else if (parsedPackage.getSigningDetails().checkCapability(
16719 sourcePackageSetting.signatures.mSigningDetails,
16720 PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
16722 // the scanned package checks out, has signing certificate rotation
16723 // history, and is newer; bring it over
16724 sourcePackageSetting.signatures.mSigningDetails =
16725 parsedPackage.getSigningDetails();
16732 // If the owning package is the system itself, we log but allow
16733 // install to proceed; we fail the install on all other permission
16735 if (!sourcePackageName.equals("android")) {
16736 throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
16737 + parsedPackage.getPackageName()
16738 + " attempting to redeclare permission "
16739 + perm.getName() + " already owned by "
16740 + sourcePackageName)
16741 .conflictsWithExistingPermission(perm.getName(),
16742 sourcePackageName);
16744 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
16745 + " attempting to redeclare system permission "
16746 + perm.getName() + "; ignoring new declaration");
16747 parsedPackage.removePermission(i);
16749 } else if (!PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())) {
16750 // Prevent apps to change protection level to dangerous from any other
16751 // type as this would allow a privilege escalation where an app adds a
16752 // normal/signature permission in other app's group and later redefines
16753 // it as dangerous leading to the group auto-grant.
16754 if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_MASK_BASE)
16755 == PermissionInfo.PROTECTION_DANGEROUS) {
16756 if (bp != null && !bp.isRuntime()) {
16757 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
16758 + " trying to change a non-runtime permission "
16760 + " to runtime; keeping old protection level");
16761 perm.setProtectionLevel(bp.getProtectionLevel());
16771 // Abort update; system app can't be replaced with app on sdcard
16772 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16773 "Cannot install updates to system apps on sdcard");
16774 } else if (instantApp) {
16775 // Abort update; system app can't be replaced with an instant app
16776 throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
16777 "Cannot update a system app with an instant app");
16781 if (args.move != null) {
16782 // We did an in-place move, so dex is ready to roll
16783 scanFlags |= SCAN_NO_DEX;
16784 scanFlags |= SCAN_MOVE;
16786 synchronized (mLock) {
16787 final PackageSetting ps = mSettings.mPackages.get(pkgName);
16789 res.setError(INSTALL_FAILED_INTERNAL_ERROR,
16790 "Missing settings for moved package " + pkgName);
16793 // We moved the entire application as-is, so bring over the
16794 // previously derived ABI information.
16795 parsedPackage.setPrimaryCpuAbi(ps.primaryCpuAbiString)
16796 .setSecondaryCpuAbi(ps.secondaryCpuAbiString);
16800 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
16801 scanFlags |= SCAN_NO_DEX;
16804 final boolean extractNativeLibs = !AndroidPackageUtils.isLibrary(parsedPackage);
16805 PackageSetting pkgSetting;
16806 synchronized (mLock) {
16807 pkgSetting = mSettings.getPackageLPr(pkgName);
16809 String abiOverride =
16810 (pkgSetting == null || TextUtils.isEmpty(pkgSetting.cpuAbiOverrideString)
16811 ? args.abiOverride : pkgSetting.cpuAbiOverrideString);
16812 boolean isUpdatedSystemAppFromExistingSetting = pkgSetting != null
16813 && pkgSetting.getPkgState().isUpdatedSystemApp();
16814 AndroidPackage oldPackage = mPackages.get(pkgName);
16815 boolean isUpdatedSystemAppInferred = oldPackage != null && oldPackage.isSystem();
16816 final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
16817 derivedAbi = mInjector.getAbiHelper().derivePackageAbi(parsedPackage,
16818 isUpdatedSystemAppFromExistingSetting || isUpdatedSystemAppInferred,
16819 abiOverride, extractNativeLibs);
16820 derivedAbi.first.applyTo(parsedPackage);
16821 derivedAbi.second.applyTo(parsedPackage);
16822 } catch (PackageManagerException pme) {
16823 Slog.e(TAG, "Error deriving application ABI", pme);
16824 throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
16825 "Error deriving application ABI");
16829 if (!args.doRename(res.returnCode, parsedPackage)) {
16830 throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
16834 setUpFsVerityIfPossible(parsedPackage);
16835 } catch (InstallerException | IOException | DigestException | NoSuchAlgorithmException e) {
16836 throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
16837 "Failed to set up verity: " + e);
16841 startIntentFilterVerifications(args.user.getIdentifier(), replace, parsedPackage);
16843 if (DEBUG_DOMAIN_VERIFICATION) {
16844 Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);
16847 final PackageFreezer freezer =
16848 freezePackageForInstall(pkgName, installFlags, "installPackageLI");
16849 boolean shouldCloseFreezerBeforeReturn = true;
16851 final AndroidPackage existingPackage;
16852 String renamedPackage = null;
16853 boolean sysPkg = false;
16854 int targetScanFlags = scanFlags;
16855 int targetParseFlags = parseFlags;
16856 final PackageSetting ps;
16857 final PackageSetting disabledPs;
16858 final PackageSetting[] childPackages;
16860 if (parsedPackage.isStaticSharedLibrary()) {
16861 // Static libs have a synthetic package name containing the version
16862 // and cannot be updated as an update would get a new package name,
16863 // unless this is the exact same version code which is useful for
16865 AndroidPackage existingPkg = mPackages.get(parsedPackage.getPackageName());
16866 if (existingPkg != null
16867 && existingPkg.getLongVersionCode()
16868 != parsedPackage.getLongVersionCode()) {
16869 throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PACKAGE,
16870 "Packages declaring "
16871 + "static-shared libs cannot be updated");
16875 final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16877 final AndroidPackage oldPackage;
16878 final String pkgName11 = parsedPackage.getPackageName();
16879 final int[] allUsers;
16880 final int[] installedUsers;
16882 synchronized (mLock) {
16883 oldPackage = mPackages.get(pkgName11);
16884 existingPackage = oldPackage;
16885 if (DEBUG_INSTALL) {
16886 // TODO(b/135203078): PackageImpl.toString()
16888 "replacePackageLI: new=" + parsedPackage + ", old=" + oldPackage);
16891 ps = mSettings.mPackages.get(pkgName11);
16892 disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
16894 // verify signatures are valid
16895 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16896 if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
16897 if (!ksms.checkUpgradeKeySetLocked(ps, parsedPackage)) {
16898 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16899 "New package not signed by keys specified by upgrade-keysets: "
16903 // default to original signature matching
16904 if (!parsedPackage.getSigningDetails().checkCapability(
16905 oldPackage.getSigningDetails(),
16906 SigningDetails.CertCapabilities.INSTALLED_DATA)
16907 && !oldPackage.getSigningDetails().checkCapability(
16908 parsedPackage.getSigningDetails(),
16909 SigningDetails.CertCapabilities.ROLLBACK)) {
16910 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16911 "New package has a different signature: " + pkgName11);
16915 // don't allow a system upgrade unless the upgrade hash matches
16916 if (oldPackage.getRestrictUpdateHash() != null && oldPackage.isSystem()) {
16917 final byte[] digestBytes;
16919 final MessageDigest digest = MessageDigest.getInstance("SHA-512");
16920 updateDigest(digest, new File(parsedPackage.getBaseCodePath()));
16921 if (!ArrayUtils.isEmpty(parsedPackage.getSplitCodePaths())) {
16922 for (String path : parsedPackage.getSplitCodePaths()) {
16923 updateDigest(digest, new File(path));
16926 digestBytes = digest.digest();
16927 } catch (NoSuchAlgorithmException | IOException e) {
16928 throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
16929 "Could not compute hash: " + pkgName11);
16931 if (!Arrays.equals(oldPackage.getRestrictUpdateHash(), digestBytes)) {
16932 throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
16933 "New package fails restrict-update check: " + pkgName11);
16935 // retain upgrade restriction
16936 parsedPackage.setRestrictUpdateHash(oldPackage.getRestrictUpdateHash());
16939 // Check for shared user id changes
16940 String invalidPackageName = null;
16941 if (!Objects.equals(oldPackage.getSharedUserId(),
16942 parsedPackage.getSharedUserId())) {
16943 invalidPackageName = parsedPackage.getPackageName();
16946 if (invalidPackageName != null) {
16947 throw new PrepareFailure(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
16948 "Package " + invalidPackageName + " tried to change user "
16949 + oldPackage.getSharedUserId());
16952 // In case of rollback, remember per-user/profile install state
16953 allUsers = mUserManager.getUserIds();
16954 installedUsers = ps.queryInstalledUsers(allUsers, true);
16957 // don't allow an upgrade from full to ephemeral
16958 if (isInstantApp) {
16959 if (args.user == null || args.user.getIdentifier() == UserHandle.USER_ALL) {
16960 for (int currentUser : allUsers) {
16961 if (!ps.getInstantApp(currentUser)) {
16962 // can't downgrade from full to instant
16964 "Can't replace full app with instant app: " + pkgName11
16965 + " for user: " + currentUser);
16966 throw new PrepareFailure(
16967 PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16970 } else if (!ps.getInstantApp(args.user.getIdentifier())) {
16971 // can't downgrade from full to instant
16972 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName11
16973 + " for user: " + args.user.getIdentifier());
16974 throw new PrepareFailure(
16975 PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16980 // Update what is removed
16981 res.removedInfo = new PackageRemovedInfo(this);
16982 res.removedInfo.uid = oldPackage.getUid();
16983 res.removedInfo.removedPackage = oldPackage.getPackageName();
16984 res.removedInfo.installerPackageName = ps.installSource.installerPackageName;
16985 res.removedInfo.isStaticSharedLib = parsedPackage.getStaticSharedLibName() != null;
16986 res.removedInfo.isUpdate = true;
16987 res.removedInfo.origUsers = installedUsers;
16988 res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
16989 for (int i = 0; i < installedUsers.length; i++) {
16990 final int userId = installedUsers[i];
16991 res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
16994 sysPkg = oldPackage.isSystem();
16996 // Set the system/privileged/oem/vendor/product flags as needed
16997 final boolean privileged = oldPackage.isPrivileged();
16998 final boolean oem = oldPackage.isOem();
16999 final boolean vendor = oldPackage.isVendor();
17000 final boolean product = oldPackage.isProduct();
17001 final boolean odm = oldPackage.isOdm();
17002 final boolean systemExt = oldPackage.isSystemExt();
17003 final @ParseFlags int systemParseFlags = parseFlags;
17004 final @ScanFlags int systemScanFlags = scanFlags
17006 | (privileged ? SCAN_AS_PRIVILEGED : 0)
17007 | (oem ? SCAN_AS_OEM : 0)
17008 | (vendor ? SCAN_AS_VENDOR : 0)
17009 | (product ? SCAN_AS_PRODUCT : 0)
17010 | (odm ? SCAN_AS_ODM : 0)
17011 | (systemExt ? SCAN_AS_SYSTEM_EXT : 0);
17013 if (DEBUG_INSTALL) {
17014 Slog.d(TAG, "replaceSystemPackageLI: new=" + parsedPackage
17015 + ", old=" + oldPackage);
17017 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17018 targetParseFlags = systemParseFlags;
17019 targetScanFlags = systemScanFlags;
17020 } else { // non system replace
17022 if (DEBUG_INSTALL) {
17024 "replaceNonSystemPackageLI: new=" + parsedPackage + ", old="
17028 } else { // new package install
17032 existingPackage = null;
17033 // Remember this for later, in case we need to rollback this install
17034 String pkgName1 = parsedPackage.getPackageName();
17036 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + parsedPackage);
17038 // TODO(patb): MOVE TO RECONCILE
17039 synchronized (mLock) {
17040 renamedPackage = mSettings.getRenamedPackageLPr(pkgName1);
17041 if (renamedPackage != null) {
17042 // A package with the same name is already installed, though
17043 // it has been renamed to an older name. The package we
17044 // are trying to install should be installed as an update to
17045 // the existing one, but that has not been requested, so bail.
17046 throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS,
17047 "Attempt to re-install " + pkgName1
17048 + " without first uninstalling package running as "
17051 if (mPackages.containsKey(pkgName1)) {
17052 // Don't allow installation over an existing package with the same name.
17053 throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS,
17054 "Attempt to re-install " + pkgName1
17055 + " without first uninstalling.");
17059 // we're passing the freezer back to be closed in a later phase of install
17060 shouldCloseFreezerBeforeReturn = false;
17062 return new PrepareResult(replace, targetScanFlags, targetParseFlags,
17063 existingPackage, parsedPackage, replace /* clearCodeCache */, sysPkg,
17066 res.freezer = freezer;
17067 if (shouldCloseFreezerBeforeReturn) {
17074 * Set up fs-verity for the given package if possible. This requires a feature flag of system
17075 * property to be enabled only if the kernel supports fs-verity.
17077 * <p>When the feature flag is set to legacy mode, only APK is supported (with some experimental
17078 * kernel patches). In normal mode, all file format can be supported.
17080 private void setUpFsVerityIfPossible(AndroidPackage pkg) throws InstallerException,
17081 PrepareFailure, IOException, DigestException, NoSuchAlgorithmException {
17082 final boolean standardMode = PackageManagerServiceUtils.isApkVerityEnabled();
17083 final boolean legacyMode = PackageManagerServiceUtils.isLegacyApkVerityEnabled();
17084 if (!standardMode && !legacyMode) {
17088 // Collect files we care for fs-verity setup.
17089 ArrayMap<String, String> fsverityCandidates = new ArrayMap<>();
17091 synchronized (mLock) {
17092 final PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
17093 if (ps != null && ps.isPrivileged()) {
17094 fsverityCandidates.put(pkg.getBaseCodePath(), null);
17095 if (pkg.getSplitCodePaths() != null) {
17096 for (String splitPath : pkg.getSplitCodePaths()) {
17097 fsverityCandidates.put(splitPath, null);
17103 // NB: These files will become only accessible if the signing key is loaded in kernel's
17104 // .fs-verity keyring.
17105 fsverityCandidates.put(pkg.getBaseCodePath(),
17106 VerityUtils.getFsveritySignatureFilePath(pkg.getBaseCodePath()));
17108 final String dmPath = DexMetadataHelper.buildDexMetadataPathForApk(
17109 pkg.getBaseCodePath());
17110 if (new File(dmPath).exists()) {
17111 fsverityCandidates.put(dmPath, VerityUtils.getFsveritySignatureFilePath(dmPath));
17114 if (pkg.getSplitCodePaths() != null) {
17115 for (String path : pkg.getSplitCodePaths()) {
17116 fsverityCandidates.put(path, VerityUtils.getFsveritySignatureFilePath(path));
17118 final String splitDmPath = DexMetadataHelper.buildDexMetadataPathForApk(path);
17119 if (new File(splitDmPath).exists()) {
17120 fsverityCandidates.put(splitDmPath,
17121 VerityUtils.getFsveritySignatureFilePath(splitDmPath));
17127 for (Map.Entry<String, String> entry : fsverityCandidates.entrySet()) {
17128 final String filePath = entry.getKey();
17129 final String signaturePath = entry.getValue();
17132 // fs-verity is optional for now. Only set up if signature is provided.
17133 if (new File(signaturePath).exists() && !VerityUtils.hasFsverity(filePath)) {
17135 VerityUtils.setUpFsverity(filePath, signaturePath);
17136 } catch (IOException e) {
17137 throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
17138 "Failed to enable fs-verity: " + e);
17144 // In legacy mode, fs-verity can only be enabled by process with CAP_SYS_ADMIN.
17145 final VerityUtils.SetupResult result = VerityUtils.generateApkVeritySetupData(filePath);
17146 if (result.isOk()) {
17147 if (Build.IS_DEBUGGABLE) Slog.i(TAG, "Enabling verity to " + filePath);
17148 final FileDescriptor fd = result.getUnownedFileDescriptor();
17150 final byte[] rootHash = VerityUtils.generateApkVerityRootHash(filePath);
17152 // A file may already have fs-verity, e.g. when reused during a split
17153 // install. If the measurement succeeds, no need to attempt to set up.
17154 mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
17155 } catch (InstallerException e) {
17156 mInstaller.installApkVerity(filePath, fd, result.getContentSize());
17157 mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
17160 IoUtils.closeQuietly(fd);
17162 } else if (result.isFailed()) {
17163 throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
17164 "Failed to generate verity");
17169 private void startIntentFilterVerifications(int userId, boolean replacing, AndroidPackage pkg) {
17170 if (mIntentFilterVerifierComponent == null) {
17171 Slog.w(TAG, "No IntentFilter verification will not be done as "
17172 + "there is no IntentFilterVerifier available!");
17176 final int verifierUid = getPackageUid(
17177 mIntentFilterVerifierComponent.getPackageName(),
17178 MATCH_DEBUG_TRIAGED_MISSING,
17179 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
17181 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17182 msg.obj = new IFVerificationParams(
17183 pkg.getPackageName(),
17184 pkg.isHasDomainUrls(),
17185 pkg.getActivities(),
17190 mHandler.sendMessage(msg);
17193 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
17194 String packageName,
17195 boolean hasDomainUrls,
17196 List<ParsedActivity> activities) {
17197 int size = activities.size();
17199 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17200 "No activity, so no need to verify any IntentFilter!");
17204 if (!hasDomainUrls) {
17205 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17206 "No domain URLs, so no need to verify any IntentFilter!");
17210 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
17211 + " if any IntentFilter from the " + size
17212 + " Activities needs verification ...");
17215 boolean handlesWebUris = false;
17216 final boolean alreadyVerified;
17217 synchronized (mLock) {
17218 // If this is a new install and we see that we've already run verification for this
17219 // package, we have nothing to do: it means the state was restored from backup.
17220 final IntentFilterVerificationInfo ivi =
17221 mSettings.getIntentFilterVerificationLPr(packageName);
17222 alreadyVerified = (ivi != null);
17223 if (!replacing && alreadyVerified) {
17224 if (DEBUG_DOMAIN_VERIFICATION) {
17225 Slog.i(TAG, "Package " + packageName + " already verified: status="
17226 + ivi.getStatusString());
17231 // If any filters need to be verified, then all need to be. In addition, we need to
17232 // know whether an updating app has any web navigation intent filters, to re-
17233 // examine handling policy even if not re-verifying.
17234 boolean needToVerify = false;
17235 for (ParsedActivity a : activities) {
17236 for (ParsedIntentInfo filter : a.getIntents()) {
17237 if (filter.handlesWebUris(true)) {
17238 handlesWebUris = true;
17240 if (filter.needsVerification()
17241 && needsNetworkVerificationLPr(a.getPackageName())) {
17242 if (DEBUG_DOMAIN_VERIFICATION) {
17244 "Intent filter needs verification, so processing all filters");
17246 needToVerify = true;
17247 // It's safe to break out here because filter.needsVerification()
17248 // can only be true if filter.handlesWebUris(true) returns true, so
17249 // we've already noted that.
17255 // Note whether this app publishes any web navigation handling support at all,
17256 // and whether there are any web-nav filters that fit the profile for running
17257 // a verification pass now.
17258 if (needToVerify) {
17259 final int verificationId = mIntentFilterVerificationToken++;
17260 for (ParsedActivity a : activities) {
17261 for (ParsedIntentInfo filter : a.getIntents()) {
17262 if (filter.handlesWebUris(true)
17263 && needsNetworkVerificationLPr(a.getPackageName())) {
17264 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17265 "Verification needed for IntentFilter:" + filter.toString());
17266 mIntentFilterVerifier.addOneIntentFilterVerification(
17267 verifierUid, userId, verificationId, filter, packageName);
17276 // count > 0 means that we're running a full verification pass
17277 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17278 + " IntentFilter verification" + (count > 1 ? "s" : "")
17279 + " for userId:" + userId);
17280 mIntentFilterVerifier.startVerifications(userId);
17281 } else if (alreadyVerified && handlesWebUris) {
17282 // App used autoVerify in the past, no longer does, but still handles web
17283 // navigation starts.
17284 if (DEBUG_DOMAIN_VERIFICATION) {
17285 Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy");
17287 synchronized (mLock) {
17288 clearIntentFilterVerificationsLPw(packageName, userId);
17291 if (DEBUG_DOMAIN_VERIFICATION) {
17292 Slog.d(TAG, "No web filters or no prior verify policy for " + packageName);
17297 @GuardedBy("mLock")
17298 private boolean needsNetworkVerificationLPr(String packageName) {
17299 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17304 int status = ivi.getStatus();
17306 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17307 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
17308 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17317 private static boolean isExternal(PackageSetting ps) {
17318 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17321 private static boolean isSystemApp(PackageSetting ps) {
17322 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17325 private static boolean isUpdatedSystemApp(PackageSetting ps) {
17326 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17329 private VersionInfo getSettingsVersionForPackage(AndroidPackage pkg) {
17330 if (pkg.isExternalStorage()) {
17331 if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
17332 return mSettings.getExternalVersion();
17334 return mSettings.findOrCreateVersion(pkg.getVolumeUuid());
17337 return mSettings.getInternalVersion();
17342 public void deletePackageAsUser(String packageName, int versionCode,
17343 IPackageDeleteObserver observer, int userId, int flags) {
17344 deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17345 new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17349 public void deletePackageVersioned(VersionedPackage versionedPackage,
17350 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17351 final int callingUid = Binder.getCallingUid();
17352 mContext.enforceCallingOrSelfPermission(
17353 android.Manifest.permission.DELETE_PACKAGES, null);
17354 final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
17355 Preconditions.checkNotNull(versionedPackage);
17356 Preconditions.checkNotNull(observer);
17357 Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
17358 PackageManager.VERSION_CODE_HIGHEST,
17359 Long.MAX_VALUE, "versionCode must be >= -1");
17361 final String packageName = versionedPackage.getPackageName();
17362 final long versionCode = versionedPackage.getLongVersionCode();
17363 final String internalPackageName;
17364 synchronized (mLock) {
17365 // Normalize package name to handle renamed packages and static libs
17366 internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
17369 final int uid = Binder.getCallingUid();
17370 if (!isOrphaned(internalPackageName)
17371 && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17372 mHandler.post(() -> {
17374 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17375 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17376 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17377 observer.onUserActionRequired(intent);
17378 } catch (RemoteException re) {
17383 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17384 final int[] users = deleteAllUsers ? mUserManager.getUserIds() : new int[]{userId};
17385 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17386 mContext.enforceCallingOrSelfPermission(
17387 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17388 "deletePackage for user " + userId);
17391 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17392 mHandler.post(() -> {
17394 observer.onPackageDeleted(packageName,
17395 PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17396 } catch (RemoteException re) {
17402 if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17403 mHandler.post(() -> {
17405 observer.onPackageDeleted(packageName,
17406 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17407 } catch (RemoteException re) {
17413 if (DEBUG_REMOVE) {
17414 Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17415 + " deleteAllUsers: " + deleteAllUsers + " version="
17416 + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17417 ? "VERSION_CODE_HIGHEST" : versionCode));
17419 // Queue up an async operation since the package deletion may take a little while.
17420 mHandler.post(() -> {
17422 final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
17423 boolean doDeletePackage = true;
17425 final boolean targetIsInstantApp =
17426 ps.getInstantApp(UserHandle.getUserId(callingUid));
17427 doDeletePackage = !targetIsInstantApp
17428 || canViewInstantApps;
17430 if (doDeletePackage) {
17431 if (!deleteAllUsers) {
17432 returnCode = deletePackageX(internalPackageName, versionCode,
17433 userId, deleteFlags);
17435 int[] blockUninstallUserIds = getBlockUninstallForUsers(
17436 internalPackageName, users);
17437 // If nobody is blocking uninstall, proceed with delete for all users
17438 if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17439 returnCode = deletePackageX(internalPackageName, versionCode,
17440 userId, deleteFlags);
17442 // Otherwise uninstall individually for users with blockUninstalls=false
17443 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17444 for (int userId1 : users) {
17445 if (!ArrayUtils.contains(blockUninstallUserIds, userId1)) {
17446 returnCode = deletePackageX(internalPackageName, versionCode,
17447 userId1, userFlags);
17448 if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17449 Slog.w(TAG, "Package delete failed for user " + userId1
17450 + ", returnCode " + returnCode);
17454 // The app has only been marked uninstalled for certain users.
17455 // We still need to report that delete was blocked
17456 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17460 returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17463 observer.onPackageDeleted(packageName, returnCode, null);
17464 } catch (RemoteException e) {
17465 Log.i(TAG, "Observer no longer exists.");
17470 private String resolveExternalPackageNameLPr(AndroidPackage pkg) {
17471 if (pkg.getStaticSharedLibName() != null) {
17472 return pkg.getManifestPackageName();
17474 return pkg.getPackageName();
17477 @GuardedBy("mLock")
17478 private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
17479 final int callingUid = Binder.getCallingUid();
17480 return resolveInternalPackageNameInternalLocked(packageName, versionCode,
17484 private String resolveInternalPackageNameInternalLocked(
17485 String packageName, long versionCode, int callingUid) {
17486 // Handle renamed packages
17487 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17488 packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17490 // Is this a static library?
17491 LongSparseArray<SharedLibraryInfo> versionedLib =
17492 mStaticLibsByDeclaringPackage.get(packageName);
17493 if (versionedLib == null || versionedLib.size() <= 0) {
17494 return packageName;
17497 // Figure out which lib versions the caller can see
17498 LongSparseLongArray versionsCallerCanSee = null;
17499 final int callingAppId = UserHandle.getAppId(callingUid);
17500 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17501 && callingAppId != Process.ROOT_UID) {
17502 versionsCallerCanSee = new LongSparseLongArray();
17503 String libName = versionedLib.valueAt(0).getName();
17504 String[] uidPackages = getPackagesForUidInternal(callingUid, callingUid);
17505 if (uidPackages != null) {
17506 for (String uidPackage : uidPackages) {
17507 PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17508 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17510 final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
17511 versionsCallerCanSee.append(libVersion, libVersion);
17517 // Caller can see nothing - done
17518 if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17519 return packageName;
17522 // Find the version the caller can see and the app version code
17523 SharedLibraryInfo highestVersion = null;
17524 final int versionCount = versionedLib.size();
17525 for (int i = 0; i < versionCount; i++) {
17526 SharedLibraryInfo libraryInfo = versionedLib.valueAt(i);
17527 if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17528 libraryInfo.getLongVersion()) < 0) {
17531 final long libVersionCode = libraryInfo.getDeclaringPackage().getLongVersionCode();
17532 if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17533 if (libVersionCode == versionCode) {
17534 return libraryInfo.getPackageName();
17536 } else if (highestVersion == null) {
17537 highestVersion = libraryInfo;
17538 } else if (libVersionCode > highestVersion
17539 .getDeclaringPackage().getLongVersionCode()) {
17540 highestVersion = libraryInfo;
17544 if (highestVersion != null) {
17545 return highestVersion.getPackageName();
17548 return packageName;
17551 boolean isCallerVerifier(int callingUid) {
17552 final int callingUserId = UserHandle.getUserId(callingUid);
17553 return mRequiredVerifierPackage != null &&
17554 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
17557 private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17558 if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17559 || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
17562 final int callingUserId = UserHandle.getUserId(callingUid);
17563 // If the caller installed the pkgName, then allow it to silently uninstall.
17564 if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
17568 // Allow package verifier to silently uninstall.
17569 if (mRequiredVerifierPackage != null &&
17570 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
17574 // Allow package uninstaller to silently uninstall.
17575 if (mRequiredUninstallerPackage != null &&
17576 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
17580 // Allow storage manager to silently uninstall.
17581 if (mStorageManagerPackage != null &&
17582 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
17586 // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
17587 // uninstall for device owner provisioning.
17588 if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
17589 == PERMISSION_GRANTED) {
17596 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
17597 int[] result = EMPTY_INT_ARRAY;
17598 for (int userId : userIds) {
17599 if (getBlockUninstallForUser(packageName, userId)) {
17600 result = ArrayUtils.appendInt(result, userId);
17607 public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
17608 final int callingUid = Binder.getCallingUid();
17609 if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
17610 != PERMISSION_GRANTED) {
17611 EventLog.writeEvent(0x534e4554, "128599183", -1, "");
17612 throw new SecurityException(android.Manifest.permission.MANAGE_USERS
17613 + " permission is required to call this API");
17615 if (getInstantAppPackageName(callingUid) != null
17616 && !isCallerSameApp(packageName, callingUid)) {
17619 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
17622 private boolean isPackageDeviceAdmin(String packageName, int userId) {
17623 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
17624 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
17627 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
17628 /* callingUserOnly =*/ false);
17629 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
17630 : deviceOwnerComponentName.getPackageName();
17631 // Does the package contains the device owner?
17632 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise,
17633 // this check is probably not needed, since DO should be registered as a device
17634 // admin on some user too. (Original bug for this: b/17657954)
17635 if (packageName.equals(deviceOwnerPackageName)) {
17638 // Does it contain a device admin for any user?
17640 if (userId == UserHandle.USER_ALL) {
17641 users = mUserManager.getUserIds();
17643 users = new int[]{userId};
17645 for (int i = 0; i < users.length; ++i) {
17646 if (dpm.packageHasActiveAdmins(packageName, users[i])) {
17651 } catch (RemoteException e) {
17656 private boolean shouldKeepUninstalledPackageLPr(String packageName) {
17657 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
17661 * This method is an internal method that could be get invoked either
17662 * to delete an installed package or to clean up a failed installation.
17663 * After deleting an installed package, a broadcast is sent to notify any
17664 * listeners that the package has been removed. For cleaning up a failed
17665 * installation, the broadcast is not necessary since the package's
17666 * installation wouldn't have sent the initial broadcast either
17667 * The key steps in deleting a package are
17668 * deleting the package information in internal structures like mPackages,
17669 * deleting the packages base directories through installd
17670 * updating mSettings to reflect current status
17671 * persisting settings for later use
17672 * sending a broadcast if necessary
17674 int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
17675 final PackageRemovedInfo info = new PackageRemovedInfo(this);
17678 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
17679 ? UserHandle.USER_ALL : userId;
17681 if (isPackageDeviceAdmin(packageName, removeUser)) {
17682 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
17683 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
17686 final PackageSetting uninstalledPs;
17687 final PackageSetting disabledSystemPs;
17688 final AndroidPackage pkg;
17690 // for the uninstall-updates case and restricted profiles, remember the per-
17691 // user handle installed state
17693 /** enabled state of the uninstalled application */
17694 final int origEnabledState;
17695 synchronized (mLock) {
17696 uninstalledPs = mSettings.mPackages.get(packageName);
17697 if (uninstalledPs == null) {
17698 Slog.w(TAG, "Not removing non-existent package " + packageName);
17699 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17702 if (versionCode != PackageManager.VERSION_CODE_HIGHEST
17703 && uninstalledPs.versionCode != versionCode) {
17704 Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
17705 + uninstalledPs.versionCode + " != " + versionCode);
17706 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17709 disabledSystemPs = mSettings.getDisabledSystemPkgLPr(packageName);
17710 // Save the enabled state before we delete the package. When deleting a stub
17711 // application we always set the enabled state to 'disabled'.
17712 origEnabledState = uninstalledPs == null
17713 ? COMPONENT_ENABLED_STATE_DEFAULT : uninstalledPs.getEnabled(userId);
17714 // Static shared libs can be declared by any package, so let us not
17715 // allow removing a package if it provides a lib others depend on.
17716 pkg = mPackages.get(packageName);
17718 allUsers = mUserManager.getUserIds();
17720 if (pkg != null && pkg.getStaticSharedLibName() != null) {
17721 SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(
17722 pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion());
17723 if (libraryInfo != null) {
17724 for (int currUserId : allUsers) {
17725 if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
17728 List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
17729 libraryInfo, MATCH_KNOWN_PACKAGES, currUserId);
17730 if (!ArrayUtils.isEmpty(libClientPackages)) {
17731 Slog.w(TAG, "Not removing package " + pkg.getManifestPackageName()
17732 + " hosting lib " + libraryInfo.getName() + " version "
17733 + libraryInfo.getLongVersion() + " used by " + libClientPackages
17734 + " for user " + currUserId);
17735 return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
17741 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
17744 final int freezeUser;
17745 if (isUpdatedSystemApp(uninstalledPs)
17746 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
17747 // We're downgrading a system app, which will apply to all users, so
17748 // freeze them all during the downgrade
17749 freezeUser = UserHandle.USER_ALL;
17751 freezeUser = removeUser;
17754 synchronized (mInstallLock) {
17755 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
17756 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
17757 deleteFlags, "deletePackageX")) {
17758 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
17759 deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
17761 synchronized (mLock) {
17764 mInstantAppRegistry.onPackageUninstalledLPw(pkg, uninstalledPs,
17765 info.removedUsers);
17767 updateSequenceNumberLP(uninstalledPs, info.removedUsers);
17768 updateInstantAppInstallerLocked(packageName);
17774 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
17775 info.sendPackageRemovedBroadcasts(killApp);
17776 info.sendSystemPackageUpdatedBroadcasts();
17777 info.sendSystemPackageAppearedBroadcasts();
17779 // Force a gc here.
17780 Runtime.getRuntime().gc();
17781 // Delete the resources here after sending the broadcast to let
17782 // other processes clean up before deleting resources.
17783 synchronized (mInstallLock) {
17784 if (info.args != null) {
17785 info.args.doPostDeleteLI(true);
17787 final AndroidPackage stubPkg =
17788 (disabledSystemPs == null) ? null : disabledSystemPs.pkg;
17789 if (stubPkg != null && stubPkg.isStub()) {
17790 final PackageSetting stubPs;
17791 synchronized (mLock) {
17792 // restore the enabled state of the stub; the state is overwritten when
17793 // the stub is uninstalled
17794 stubPs = mSettings.getPackageLPr(stubPkg.getPackageName());
17795 if (stubPs != null) {
17796 stubPs.setEnabled(origEnabledState, userId, "android");
17799 if (origEnabledState == COMPONENT_ENABLED_STATE_DEFAULT
17800 || origEnabledState == COMPONENT_ENABLED_STATE_ENABLED) {
17801 if (DEBUG_COMPRESSION) {
17802 Slog.i(TAG, "Enabling system stub after removal; pkg: "
17803 + stubPkg.getPackageName());
17805 enableCompressedPackage(stubPkg, stubPs);
17810 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17813 static class PackageRemovedInfo {
17814 final PackageSender packageSender;
17815 String removedPackage;
17816 String installerPackageName;
17818 int removedAppId = -1;
17820 int[] removedUsers = null;
17821 int[] broadcastUsers = null;
17822 int[] instantUserIds = null;
17823 SparseArray<Integer> installReasons;
17824 boolean isRemovedPackageSystemUpdate = false;
17826 boolean dataRemoved;
17827 boolean removedForAllUsers;
17828 boolean isStaticSharedLib;
17829 // Clean up resources deleted packages.
17830 InstallArgs args = null;
17831 ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
17833 PackageRemovedInfo(PackageSender packageSender) {
17834 this.packageSender = packageSender;
17837 void sendPackageRemovedBroadcasts(boolean killApp) {
17838 sendPackageRemovedBroadcastInternal(killApp);
17841 void sendSystemPackageUpdatedBroadcasts() {
17842 if (isRemovedPackageSystemUpdate) {
17843 sendSystemPackageUpdatedBroadcastsInternal();
17847 void sendSystemPackageAppearedBroadcasts() {
17848 final int packageCount = (appearedChildPackages != null)
17849 ? appearedChildPackages.size() : 0;
17850 for (int i = 0; i < packageCount; i++) {
17851 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
17852 packageSender.sendPackageAddedForNewUsers(installedInfo.name,
17853 true /*sendBootCompleted*/, false /*startReceiver*/,
17854 UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers, null);
17858 private void sendSystemPackageUpdatedBroadcastsInternal() {
17859 Bundle extras = new Bundle(2);
17860 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
17861 extras.putBoolean(Intent.EXTRA_REPLACING, true);
17862 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17863 removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
17864 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17865 removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
17866 packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
17867 null, null, 0, removedPackage, null, null, null);
17868 if (installerPackageName != null) {
17869 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17870 removedPackage, extras, 0 /*flags*/,
17871 installerPackageName, null, null, null);
17872 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17873 removedPackage, extras, 0 /*flags*/,
17874 installerPackageName, null, null, null);
17878 private void sendPackageRemovedBroadcastInternal(boolean killApp) {
17879 // Don't send static shared library removal broadcasts as these
17880 // libs are visible only the the apps that depend on them an one
17881 // cannot remove the library if it has a dependency.
17882 if (isStaticSharedLib) {
17885 Bundle extras = new Bundle(2);
17886 final int removedUid = removedAppId >= 0 ? removedAppId : uid;
17887 extras.putInt(Intent.EXTRA_UID, removedUid);
17888 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
17889 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
17890 if (isUpdate || isRemovedPackageSystemUpdate) {
17891 extras.putBoolean(Intent.EXTRA_REPLACING, true);
17893 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
17894 if (removedPackage != null) {
17895 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17896 removedPackage, extras, 0, null /*targetPackage*/, null,
17897 broadcastUsers, instantUserIds);
17898 if (installerPackageName != null) {
17899 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17900 removedPackage, extras, 0 /*flags*/,
17901 installerPackageName, null, broadcastUsers, instantUserIds);
17903 if (dataRemoved && !isRemovedPackageSystemUpdate) {
17904 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
17905 removedPackage, extras,
17906 Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17907 null, null, broadcastUsers, instantUserIds);
17908 packageSender.notifyPackageRemoved(removedPackage, removedUid);
17911 if (removedAppId >= 0) {
17912 // If a system app's updates are uninstalled the UID is not actually removed. Some
17913 // services need to know the package name affected.
17914 if (extras.getBoolean(Intent.EXTRA_REPLACING, false)) {
17915 extras.putString(Intent.EXTRA_PACKAGE_NAME, removedPackage);
17918 packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
17919 null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17920 null, null, broadcastUsers, instantUserIds);
17924 void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
17925 removedUsers = userIds;
17926 if (removedUsers == null) {
17927 broadcastUsers = null;
17931 broadcastUsers = EMPTY_INT_ARRAY;
17932 instantUserIds = EMPTY_INT_ARRAY;
17933 for (int i = userIds.length - 1; i >= 0; --i) {
17934 final int userId = userIds[i];
17935 if (deletedPackageSetting.getInstantApp(userId)) {
17936 instantUserIds = ArrayUtils.appendInt(instantUserIds, userId);
17938 broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
17945 * This method deletes the package from internal data structures. If the DELETE_KEEP_DATA
17946 * flag is not set, the data directory is removed as well.
17947 * make sure this flag is set for partially installed apps. If not its meaningless to
17948 * delete a partially installed application.
17950 private void removePackageDataLIF(final PackageSetting deletedPs, int[] allUserHandles,
17951 PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
17952 String packageName = deletedPs.name;
17953 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + deletedPs);
17954 // Retrieve object to delete permissions for shared user later on
17955 final AndroidPackage deletedPkg = deletedPs.pkg;
17956 if (outInfo != null) {
17957 outInfo.removedPackage = packageName;
17958 outInfo.installerPackageName = deletedPs.installSource.installerPackageName;
17959 outInfo.isStaticSharedLib = deletedPkg != null
17960 && deletedPkg.getStaticSharedLibName() != null;
17961 outInfo.populateUsers(deletedPs == null ? null
17962 : deletedPs.queryInstalledUsers(mUserManager.getUserIds(), true), deletedPs);
17965 removePackageLI(deletedPs.name, (flags & PackageManager.DELETE_CHATTY) != 0);
17967 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
17968 final AndroidPackage resolvedPkg;
17969 if (deletedPkg != null) {
17970 resolvedPkg = deletedPkg;
17972 // We don't have a parsed package when it lives on an ejected
17973 // adopted storage device, so fake something together
17974 resolvedPkg = PackageImpl.buildFakeForDeletion(deletedPs.name,
17975 deletedPs.volumeUuid);
17977 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
17978 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
17979 destroyAppProfilesLIF(resolvedPkg);
17980 if (outInfo != null) {
17981 outInfo.dataRemoved = true;
17985 int removedAppId = -1;
17988 boolean installedStateChanged = false;
17989 if (deletedPs != null) {
17990 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
17991 final SparseBooleanArray changedUsers = new SparseBooleanArray();
17992 synchronized (mLock) {
17993 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
17994 clearDefaultBrowserIfNeeded(packageName);
17995 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
17996 removedAppId = mSettings.removePackageLPw(packageName);
17997 if (outInfo != null) {
17998 outInfo.removedAppId = removedAppId;
18000 mPermissionManager.updatePermissions(deletedPs.name, null);
18001 if (deletedPs.sharedUser != null) {
18002 // Remove permissions associated with package. Since runtime
18003 // permissions are per user we have to kill the removed package
18004 // or packages running under the shared user of the removed
18005 // package if revoking the permissions requested only by the removed
18006 // package is successful and this causes a change in gids.
18007 boolean shouldKill = false;
18008 for (int userId : UserManagerService.getInstance().getUserIds()) {
18009 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
18011 shouldKill |= userIdToKill == UserHandle.USER_ALL
18012 || userIdToKill >= UserHandle.USER_SYSTEM;
18014 // If gids changed, kill all affected packages.
18016 mHandler.post(() -> {
18017 // This has to happen with no lock held.
18018 killApplication(deletedPs.name, deletedPs.appId,
18019 KILL_APP_REASON_GIDS_CHANGED);
18023 clearPackagePreferredActivitiesLPw(
18024 deletedPs.name, changedUsers, UserHandle.USER_ALL);
18026 if (changedUsers.size() > 0) {
18027 updateDefaultHomeNotLocked(changedUsers);
18028 postPreferredActivityChangedBroadcast(UserHandle.USER_ALL);
18031 // make sure to preserve per-user disabled state if this removal was just
18032 // a downgrade of a system app to the factory package
18033 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18034 if (DEBUG_REMOVE) {
18035 Slog.d(TAG, "Propagating install state across downgrade");
18037 for (int userId : allUserHandles) {
18038 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18039 if (DEBUG_REMOVE) {
18040 Slog.d(TAG, " user " + userId + " => " + installed);
18042 if (installed != deletedPs.getInstalled(userId)) {
18043 installedStateChanged = true;
18045 deletedPs.setInstalled(installed, userId);
18049 synchronized (mLock) {
18050 // can downgrade to reader
18051 if (writeSettings) {
18052 // Save settings now
18053 mSettings.writeLPr();
18055 if (installedStateChanged) {
18056 mSettings.writeKernelMappingLPr(deletedPs);
18059 if (removedAppId != -1) {
18060 // A user ID was deleted here. Go through all users and remove it
18062 removeKeystoreDataIfNeeded(
18063 mInjector.getUserManagerInternal(), UserHandle.USER_ALL, removedAppId);
18067 private static @Nullable ScanPartition resolveApexToScanPartition(
18068 ApexManager.ActiveApexInfo apexInfo) {
18069 for (int i = 0, size = SYSTEM_PARTITIONS.size(); i < size; i++) {
18070 ScanPartition sp = SYSTEM_PARTITIONS.get(i);
18071 if (apexInfo.preInstalledApexPath.getAbsolutePath().startsWith(
18072 sp.folder.getAbsolutePath())) {
18073 return new ScanPartition(apexInfo.apexDirectory, sp, SCAN_AS_APK_IN_APEX);
18080 * Tries to delete system package.
18082 private void deleteSystemPackageLIF(DeletePackageAction action, PackageSetting deletedPs,
18083 int[] allUserHandles, int flags, @Nullable PackageRemovedInfo outInfo,
18084 boolean writeSettings)
18085 throws SystemDeleteException {
18086 final boolean applyUserRestrictions =
18087 (allUserHandles != null) && outInfo != null && (outInfo.origUsers != null);
18088 final AndroidPackage deletedPkg = deletedPs.pkg;
18089 // Confirm if the system package has been updated
18090 // An updated system app can be deleted. This will also have to restore
18091 // the system pkg from system partition
18093 final PackageSetting disabledPs = action.disabledPs;
18094 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.getPackageName()
18095 + " disabledPs=" + disabledPs);
18096 Slog.d(TAG, "Deleting system pkg from data partition");
18098 if (DEBUG_REMOVE) {
18099 if (applyUserRestrictions) {
18100 Slog.d(TAG, "Remembering install states:");
18101 for (int userId : allUserHandles) {
18102 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
18103 Slog.d(TAG, " u=" + userId + " inst=" + finstalled);
18108 if (outInfo != null) {
18109 // Delete the updated package
18110 outInfo.isRemovedPackageSystemUpdate = true;
18113 if (disabledPs.versionCode < deletedPs.versionCode) {
18114 // Delete data for downgrades
18115 flags &= ~PackageManager.DELETE_KEEP_DATA;
18117 // Preserve data by setting flag
18118 flags |= PackageManager.DELETE_KEEP_DATA;
18121 deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
18122 outInfo, writeSettings);
18125 synchronized (mLock) {
18126 // NOTE: The system package always needs to be enabled; even if it's for
18127 // a compressed stub. If we don't, installing the system package fails
18128 // during scan [scanning checks the disabled packages]. We will reverse
18129 // this later, after we've "installed" the stub.
18130 // Reinstate the old system package
18131 enableSystemPackageLPw(disabledPs.pkg);
18132 // Remove any native libraries from the upgraded package.
18133 removeNativeBinariesLI(deletedPs);
18136 // Install the system package
18137 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18139 installPackageFromSystemLIF(disabledPs.codePathString, allUserHandles,
18140 outInfo == null ? null : outInfo.origUsers, deletedPs.getPermissionsState(),
18142 } catch (PackageManagerException e) {
18143 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.getPackageName() + ": "
18145 // TODO(patb): can we avoid this; throw would come from scan...
18146 throw new SystemDeleteException(e);
18148 if (disabledPs.pkg.isStub()) {
18149 // We've re-installed the stub; make sure it's disabled here. If package was
18150 // originally enabled, we'll install the compressed version of the application
18151 // and re-enable it afterward.
18152 final PackageSetting stubPs = mSettings.mPackages.get(deletedPkg.getPackageName());
18153 if (stubPs != null) {
18155 COMPONENT_ENABLED_STATE_DISABLED, UserHandle.USER_SYSTEM, "android");
18162 * Installs a package that's already on the system partition.
18164 private AndroidPackage installPackageFromSystemLIF(@NonNull String codePathString,
18165 @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
18166 @Nullable PermissionsState origPermissionState, boolean writeSettings)
18167 throws PackageManagerException {
18168 @ParseFlags int parseFlags =
18170 | PackageParser.PARSE_MUST_BE_APK
18171 | PackageParser.PARSE_IS_SYSTEM_DIR;
18172 @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
18173 for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
18174 ScanPartition partition = mDirsToScanAsSystem.get(i);
18175 if (partition.containsPath(codePathString)) {
18176 scanFlags |= partition.scanFlag;
18177 if (partition.containsPrivPath(codePathString)) {
18178 scanFlags |= SCAN_AS_PRIVILEGED;
18184 final File codePath = new File(codePathString);
18185 final AndroidPackage pkg =
18186 scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
18188 PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.getPackageName());
18191 // update shared libraries for the newly re-installed system package
18192 updateSharedLibrariesLocked(pkg, pkgSetting, null, null,
18193 Collections.unmodifiableMap(mPackages));
18194 } catch (PackageManagerException e) {
18195 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18198 prepareAppDataAfterInstallLIF(pkg);
18201 synchronized (mLock) {
18202 PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
18204 // Propagate the permissions state as we do not want to drop on the floor
18205 // runtime permissions. The update permissions method below will take
18206 // care of removing obsolete permissions and grant install permissions.
18207 if (origPermissionState != null) {
18208 ps.getPermissionsState().copyFrom(origPermissionState);
18210 mPermissionManager.updatePermissions(pkg.getPackageName(), pkg);
18212 final boolean applyUserRestrictions
18213 = (allUserHandles != null) && (origUserHandles != null);
18214 if (applyUserRestrictions) {
18215 boolean installedStateChanged = false;
18216 if (DEBUG_REMOVE) {
18217 Slog.d(TAG, "Propagating install state across reinstall");
18219 for (int userId : allUserHandles) {
18220 final boolean installed = ArrayUtils.contains(origUserHandles, userId);
18221 if (DEBUG_REMOVE) {
18222 Slog.d(TAG, " user " + userId + " => " + installed);
18224 if (installed != ps.getInstalled(userId)) {
18225 installedStateChanged = true;
18227 ps.setInstalled(installed, userId);
18229 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
18231 // Regardless of writeSettings we need to ensure that this restriction
18232 // state propagation is persisted
18233 mSettings.writeAllUsersPackageRestrictionsLPr();
18234 if (installedStateChanged) {
18235 mSettings.writeKernelMappingLPr(ps);
18238 // can downgrade to reader here
18239 if (writeSettings) {
18240 mSettings.writeLPr();
18246 private void deleteInstalledPackageLIF(PackageSetting ps,
18247 boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18248 PackageRemovedInfo outInfo, boolean writeSettings) {
18249 synchronized (mLock) {
18250 if (outInfo != null) {
18251 outInfo.uid = ps.appId;
18255 // Delete package data from internal structures and also remove data if flag is set
18256 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18258 // Delete application code and resources only for parent packages
18259 if (deleteCodeAndResources && (outInfo != null)) {
18260 outInfo.args = createInstallArgsForExisting(
18261 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(
18262 ps.primaryCpuAbiString, ps.secondaryCpuAbiString));
18263 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18268 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18270 mContext.enforceCallingOrSelfPermission(
18271 android.Manifest.permission.DELETE_PACKAGES, null);
18272 synchronized (mLock) {
18273 // Cannot block uninstall of static shared libs as they are
18274 // considered a part of the using app (emulating static linking).
18275 // Also static libs are installed always on internal storage.
18276 AndroidPackage pkg = mPackages.get(packageName);
18277 if (pkg != null && pkg.getStaticSharedLibName() != null) {
18278 Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18279 + " providing static shared library: " + pkg.getStaticSharedLibName());
18282 mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
18283 mSettings.writePackageRestrictionsLPr(userId);
18289 public boolean getBlockUninstallForUser(String packageName, int userId) {
18290 synchronized (mLock) {
18291 final PackageSetting ps = mSettings.mPackages.get(packageName);
18292 if (ps == null || shouldFilterApplicationLocked(ps, Binder.getCallingUid(), userId)) {
18295 return mSettings.getBlockUninstallLPr(userId, packageName);
18300 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18301 enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
18302 synchronized (mLock) {
18303 PackageSetting ps = mSettings.mPackages.get(packageName);
18305 Log.w(TAG, "Package doesn't exist: " + packageName);
18308 if (systemUserApp) {
18309 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18311 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18313 mSettings.writeLPr();
18318 private static class DeletePackageAction {
18319 public final PackageSetting deletingPs;
18320 public final PackageSetting disabledPs;
18321 public final PackageRemovedInfo outInfo;
18322 public final int flags;
18323 public final UserHandle user;
18325 private DeletePackageAction(PackageSetting deletingPs, PackageSetting disabledPs,
18326 PackageRemovedInfo outInfo, int flags, UserHandle user) {
18327 this.deletingPs = deletingPs;
18328 this.disabledPs = disabledPs;
18329 this.outInfo = outInfo;
18330 this.flags = flags;
18336 * @return a {@link DeletePackageAction} if the provided package and related state may be
18337 * deleted, {@code null} otherwise.
18340 @GuardedBy("mLock")
18341 private static DeletePackageAction mayDeletePackageLocked(
18342 PackageRemovedInfo outInfo, PackageSetting ps, @Nullable PackageSetting disabledPs,
18343 int flags, UserHandle user) {
18347 if (isSystemApp(ps)) {
18348 final boolean deleteSystem = (flags & PackageManager.DELETE_SYSTEM_APP) != 0;
18349 final boolean deleteAllUsers =
18350 user == null || user.getIdentifier() == UserHandle.USER_ALL;
18351 if ((!deleteSystem || deleteAllUsers) && disabledPs == null) {
18352 Slog.w(TAG, "Attempt to delete unknown system package " + ps.pkg.getPackageName());
18355 // Confirmed if the system package has been updated
18356 // An updated system app can be deleted. This will also have to restore
18357 // the system pkg from system partition reader
18359 return new DeletePackageAction(ps, disabledPs, outInfo, flags, user);
18363 * This method handles package deletion in general
18365 private boolean deletePackageLIF(@NonNull String packageName, UserHandle user,
18366 boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18367 PackageRemovedInfo outInfo, boolean writeSettings,
18368 ParsedPackage replacingPackage) {
18369 final DeletePackageAction action;
18370 synchronized (mLock) {
18371 final PackageSetting ps = mSettings.mPackages.get(packageName);
18372 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
18373 action = mayDeletePackageLocked(outInfo, ps, disabledPs, flags, user);
18375 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18376 if (null == action) {
18377 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: action was null");
18383 executeDeletePackageLIF(action, packageName, deleteCodeAndResources,
18384 allUserHandles, writeSettings, replacingPackage);
18385 } catch (SystemDeleteException e) {
18386 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: system deletion failure", e);
18392 private static class SystemDeleteException extends Exception {
18393 public final PackageManagerException reason;
18395 private SystemDeleteException(PackageManagerException reason) {
18396 this.reason = reason;
18400 /** Deletes a package. Only throws when install of a disabled package fails. */
18401 private void executeDeletePackageLIF(DeletePackageAction action,
18402 String packageName, boolean deleteCodeAndResources,
18403 int[] allUserHandles, boolean writeSettings,
18404 ParsedPackage replacingPackage) throws SystemDeleteException {
18405 final PackageSetting ps = action.deletingPs;
18406 final PackageRemovedInfo outInfo = action.outInfo;
18407 final UserHandle user = action.user;
18408 final int flags = action.flags;
18409 final boolean systemApp = isSystemApp(ps);
18411 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
18412 if (ps.getPermissionsState().hasPermission(Manifest.permission.SUSPEND_APPS, userId)) {
18413 unsuspendForSuspendingPackage(packageName, userId);
18415 if ((!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)
18416 && userId != UserHandle.USER_ALL) {
18417 // The caller is asking that the package only be deleted for a single
18418 // user. To do this, we just mark its uninstalled state and delete
18419 // its data. If this is a system app, we only allow this to happen if
18420 // they have set the special DELETE_SYSTEM_APP which requests different
18421 // semantics than normal for uninstalling system apps.
18422 final boolean clearPackageStateAndReturn;
18423 synchronized (mLock) {
18424 markPackageUninstalledForUserLPw(ps, user);
18426 // Do not uninstall the APK if an app should be cached
18427 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18428 if (ps.isAnyInstalled(mUserManager.getUserIds()) || keepUninstalledPackage) {
18429 // Other users still have this package installed, so all
18430 // we need to do is clear this user's data and save that
18431 // it is uninstalled.
18432 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18433 clearPackageStateAndReturn = true;
18435 // We need to set it back to 'installed' so the uninstall
18436 // broadcasts will be sent correctly.
18437 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18438 ps.setInstalled(true, userId);
18439 mSettings.writeKernelMappingLPr(ps);
18440 clearPackageStateAndReturn = false;
18443 // This is a system app, so we assume that the
18444 // other users still have this package installed, so all
18445 // we need to do is clear this user's data and save that
18446 // it is uninstalled.
18447 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18448 clearPackageStateAndReturn = true;
18451 if (clearPackageStateAndReturn) {
18452 clearPackageStateForUserLIF(ps, userId, outInfo, flags);
18453 synchronized (mLock) {
18454 scheduleWritePackageRestrictionsLocked(user);
18460 // TODO(b/109941548): break reasons for ret = false out into mayDelete method
18462 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18463 // When an updated system application is deleted we delete the existing resources
18464 // as well and fall back to existing code in system partition
18465 deleteSystemPackageLIF(action, ps, allUserHandles, flags, outInfo, writeSettings);
18467 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18468 deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18469 outInfo, writeSettings);
18472 // Take a note whether we deleted the package for all users
18473 if (outInfo != null) {
18474 outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18478 @GuardedBy("mLock")
18479 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18480 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18481 ? mUserManager.getUserIds() : new int[] {user.getIdentifier()};
18482 for (int nextUserId : userIds) {
18483 if (DEBUG_REMOVE) {
18484 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18486 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18487 false /*installed*/,
18489 true /*notLaunched*/,
18491 0 /*distractionFlags*/,
18492 false /*suspended*/,
18493 null /*suspendParams*/,
18494 false /*instantApp*/,
18495 false /*virtualPreload*/,
18496 null /*lastDisableAppCaller*/,
18497 null /*enabledComponents*/,
18498 null /*disabledComponents*/,
18499 ps.readUserState(nextUserId).domainVerificationStatus,
18500 0, PackageManager.INSTALL_REASON_UNKNOWN,
18501 null /*harmfulAppWarning*/);
18503 mSettings.writeKernelMappingLPr(ps);
18506 private void clearPackageStateForUserLIF(PackageSetting ps, int userId,
18507 PackageRemovedInfo outInfo, int flags) {
18508 final AndroidPackage pkg;
18509 synchronized (mLock) {
18510 pkg = mPackages.get(ps.name);
18513 destroyAppProfilesLIF(pkg);
18515 final int[] userIds = (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds()
18516 : new int[] {userId};
18517 for (int nextUserId : userIds) {
18518 if (DEBUG_REMOVE) {
18519 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18523 destroyAppDataLIF(pkg, nextUserId,
18524 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
18525 clearDefaultBrowserIfNeededForUser(ps.name, nextUserId);
18526 removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), nextUserId, ps.appId);
18527 clearPackagePreferredActivities(ps.name, nextUserId);
18528 mPermissionManager.resetRuntimePermissions(pkg, nextUserId);
18531 if (outInfo != null) {
18532 outInfo.removedPackage = ps.name;
18533 outInfo.installerPackageName = ps.installSource.installerPackageName;
18534 outInfo.isStaticSharedLib = pkg != null && pkg.getStaticSharedLibName() != null;
18535 outInfo.removedAppId = ps.appId;
18536 outInfo.removedUsers = userIds;
18537 outInfo.broadcastUsers = userIds;
18542 public void clearApplicationProfileData(String packageName) {
18543 enforceSystemOrRoot("Only the system can clear all profile data");
18545 final AndroidPackage pkg;
18546 synchronized (mLock) {
18547 pkg = mPackages.get(packageName);
18550 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
18551 synchronized (mInstallLock) {
18552 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
18558 public void clearApplicationUserData(final String packageName,
18559 final IPackageDataObserver observer, final int userId) {
18560 mContext.enforceCallingOrSelfPermission(
18561 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
18563 final int callingUid = Binder.getCallingUid();
18564 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18565 true /* requireFullPermission */, false /* checkShell */, "clear application data");
18567 final PackageSetting ps = mSettings.getPackageLPr(packageName);
18568 final boolean filterApp =
18569 (ps != null && shouldFilterApplicationLocked(ps, callingUid, userId));
18570 if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
18571 throw new SecurityException("Cannot clear data for a protected package: "
18574 // Queue up an async operation since the package deletion may take a little while.
18575 mHandler.post(new Runnable() {
18576 public void run() {
18577 mHandler.removeCallbacks(this);
18578 final boolean succeeded;
18580 try (PackageFreezer freezer = freezePackage(packageName,
18581 "clearApplicationUserData")) {
18582 synchronized (mInstallLock) {
18583 succeeded = clearApplicationUserDataLIF(packageName, userId);
18585 synchronized (mLock) {
18586 mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
18587 packageName, userId);
18591 // invoke DeviceStorageMonitor's update method to clear any notifications
18592 DeviceStorageMonitorInternal dsm = LocalServices
18593 .getService(DeviceStorageMonitorInternal.class);
18597 if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
18598 == PERMISSION_GRANTED) {
18599 unsuspendForSuspendingPackage(packageName, userId);
18600 removeAllDistractingPackageRestrictions(userId);
18601 flushPackageRestrictionsAsUserInternalLocked(userId);
18607 if (observer != null) {
18609 observer.onRemoveCompleted(packageName, succeeded);
18610 } catch (RemoteException e) {
18611 Log.i(TAG, "Observer no longer exists.");
18613 } //end if observer
18618 private boolean clearApplicationUserDataLIF(String packageName, int userId) {
18619 if (packageName == null) {
18620 Slog.w(TAG, "Attempt to delete null packageName.");
18624 // Try finding details about the requested package
18625 AndroidPackage pkg;
18627 synchronized (mLock) {
18628 pkg = mPackages.get(packageName);
18629 ps = mSettings.mPackages.get(packageName);
18637 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18640 mPermissionManager.resetRuntimePermissions(pkg, userId);
18642 clearAppDataLIF(pkg, userId,
18643 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
18645 final int appId = UserHandle.getAppId(pkg.getUid());
18646 removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), userId, appId);
18648 UserManagerInternal umInternal = mInjector.getUserManagerInternal();
18650 if (umInternal.isUserUnlockingOrUnlocked(userId)) {
18651 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18652 } else if (umInternal.isUserRunning(userId)) {
18653 flags = StorageManager.FLAG_STORAGE_DE;
18657 prepareAppDataContentsLIF(pkg, ps, userId, flags);
18662 private void resetNetworkPolicies(int userId) {
18663 mInjector.getNetworkPolicyManagerInternal().resetUserState(userId);
18667 * Remove entries from the keystore daemon. Will only remove it if the
18668 * {@code appId} is valid.
18670 private static void removeKeystoreDataIfNeeded(UserManagerInternal um, @UserIdInt int userId,
18671 @AppIdInt int appId) {
18676 final KeyStore keyStore = KeyStore.getInstance();
18677 if (keyStore != null) {
18678 if (userId == UserHandle.USER_ALL) {
18679 for (final int individual : um.getUserIds()) {
18680 keyStore.clearUid(UserHandle.getUid(individual, appId));
18683 keyStore.clearUid(UserHandle.getUid(userId, appId));
18686 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
18691 public void deleteApplicationCacheFiles(final String packageName,
18692 final IPackageDataObserver observer) {
18693 final int userId = UserHandle.getCallingUserId();
18694 deleteApplicationCacheFilesAsUser(packageName, userId, observer);
18698 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
18699 final IPackageDataObserver observer) {
18700 final int callingUid = Binder.getCallingUid();
18701 if (mContext.checkCallingOrSelfPermission(
18702 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES)
18703 != PackageManager.PERMISSION_GRANTED) {
18704 // If the caller has the old delete cache permission, silently ignore. Else throw.
18705 if (mContext.checkCallingOrSelfPermission(
18706 android.Manifest.permission.DELETE_CACHE_FILES)
18707 == PackageManager.PERMISSION_GRANTED) {
18708 Slog.w(TAG, "Calling uid " + callingUid + " does not have " +
18709 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES +
18710 ", silently ignoring");
18713 mContext.enforceCallingOrSelfPermission(
18714 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
18716 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18717 /* requireFullPermission= */ true, /* checkShell= */ false,
18718 "delete application cache files");
18719 final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
18720 android.Manifest.permission.ACCESS_INSTANT_APPS);
18722 final AndroidPackage pkg;
18723 synchronized (mLock) {
18724 pkg = mPackages.get(packageName);
18727 // Queue up an async operation since the package deletion may take a little while.
18728 mHandler.post(() -> {
18729 final PackageSetting ps = pkg == null ? null : getPackageSetting(pkg.getPackageName());
18730 boolean doClearData = true;
18732 final boolean targetIsInstantApp =
18733 ps.getInstantApp(UserHandle.getUserId(callingUid));
18734 doClearData = !targetIsInstantApp
18735 || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
18738 synchronized (mInstallLock) {
18739 final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL;
18740 // We're only clearing cache files, so we don't care if the
18741 // app is unfrozen and still able to run
18742 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
18743 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18746 if (observer != null) {
18748 observer.onRemoveCompleted(packageName, true);
18749 } catch (RemoteException e) {
18750 Log.i(TAG, "Observer no longer exists.");
18757 public void getPackageSizeInfo(final String packageName, int userId,
18758 final IPackageStatsObserver observer) {
18759 throw new UnsupportedOperationException(
18760 "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
18763 @GuardedBy("mInstallLock")
18764 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
18765 final PackageSetting ps;
18766 synchronized (mLock) {
18767 ps = mSettings.mPackages.get(packageName);
18769 Slog.w(TAG, "Failed to find settings for " + packageName);
18774 final String[] packageNames = { packageName };
18775 final long[] ceDataInodes = { ps.getCeDataInode(userId) };
18776 final String[] codePaths = { ps.codePathString };
18779 mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
18780 ps.appId, ceDataInodes, codePaths, stats);
18782 // For now, ignore code size of packages on system partition
18783 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
18784 stats.codeSize = 0;
18787 // External clients expect these to be tracked separately
18788 stats.dataSize -= stats.cacheSize;
18790 } catch (InstallerException e) {
18791 Slog.w(TAG, String.valueOf(e));
18798 @GuardedBy("mLock")
18799 private int getUidTargetSdkVersionLockedLPr(int uid) {
18800 final int appId = UserHandle.getAppId(uid);
18801 final Object obj = mSettings.getSettingLPr(appId);
18802 if (obj instanceof SharedUserSetting) {
18803 final SharedUserSetting sus = (SharedUserSetting) obj;
18804 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
18805 final Iterator<PackageSetting> it = sus.packages.iterator();
18806 while (it.hasNext()) {
18807 final PackageSetting ps = it.next();
18808 if (ps.pkg != null) {
18809 int v = ps.pkg.getTargetSdkVersion();
18810 if (v < vers) vers = v;
18814 } else if (obj instanceof PackageSetting) {
18815 final PackageSetting ps = (PackageSetting) obj;
18816 if (ps.pkg != null) {
18817 return ps.pkg.getTargetSdkVersion();
18820 return Build.VERSION_CODES.CUR_DEVELOPMENT;
18823 @GuardedBy("mLock")
18824 private int getPackageTargetSdkVersionLockedLPr(String packageName) {
18825 final AndroidPackage p = mPackages.get(packageName);
18827 return p.getTargetSdkVersion();
18829 return Build.VERSION_CODES.CUR_DEVELOPMENT;
18833 public void addPreferredActivity(IntentFilter filter, int match,
18834 ComponentName[] set, ComponentName activity, int userId) {
18835 addPreferredActivityInternal(filter, match, set, activity, true, userId,
18836 "Adding preferred");
18839 private void addPreferredActivityInternal(IntentFilter filter, int match,
18840 ComponentName[] set, ComponentName activity, boolean always, int userId,
18843 int callingUid = Binder.getCallingUid();
18844 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18845 true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
18846 if (mContext.checkCallingOrSelfPermission(
18847 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18848 != PackageManager.PERMISSION_GRANTED) {
18849 if (getUidTargetSdkVersionLockedLPr(callingUid)
18850 < Build.VERSION_CODES.FROYO) {
18851 Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
18855 mContext.enforceCallingOrSelfPermission(
18856 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18858 if (filter.countActions() == 0) {
18859 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
18862 if (DEBUG_PREFERRED) {
18863 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
18865 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
18867 synchronized (mLock) {
18868 final PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
18869 pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
18870 scheduleWritePackageRestrictionsLocked(userId);
18872 if (!updateDefaultHomeNotLocked(userId)) {
18873 postPreferredActivityChangedBroadcast(userId);
18877 private void postPreferredActivityChangedBroadcast(int userId) {
18878 mHandler.post(() -> {
18879 final IActivityManager am = ActivityManager.getService();
18884 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
18885 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18886 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
18888 am.broadcastIntentWithFeature(null, null, intent, null, null,
18889 0, null, null, null, android.app.AppOpsManager.OP_NONE,
18890 null, false, false, userId);
18891 } catch (RemoteException e) {
18897 public void replacePreferredActivity(IntentFilter filter, int match,
18898 ComponentName[] set, ComponentName activity, int userId) {
18899 if (filter.countActions() != 1) {
18900 throw new IllegalArgumentException(
18901 "replacePreferredActivity expects filter to have only 1 action.");
18903 if (filter.countDataAuthorities() != 0
18904 || filter.countDataPaths() != 0
18905 || filter.countDataSchemes() > 1
18906 || filter.countDataTypes() != 0) {
18907 throw new IllegalArgumentException(
18908 "replacePreferredActivity expects filter to have no data authorities, " +
18909 "paths, or types; and at most one scheme.");
18912 final int callingUid = Binder.getCallingUid();
18913 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18914 true /* requireFullPermission */, false /* checkShell */,
18915 "replace preferred activity");
18916 if (mContext.checkCallingOrSelfPermission(
18917 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18918 != PackageManager.PERMISSION_GRANTED) {
18919 synchronized (mLock) {
18920 if (getUidTargetSdkVersionLockedLPr(callingUid)
18921 < Build.VERSION_CODES.FROYO) {
18922 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
18923 + Binder.getCallingUid());
18927 mContext.enforceCallingOrSelfPermission(
18928 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18931 synchronized (mLock) {
18932 final PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
18934 // Get all of the existing entries that exactly match this filter.
18935 final ArrayList<PreferredActivity> existing = pir.findFilters(filter);
18936 if (existing != null && existing.size() == 1) {
18937 final PreferredActivity cur = existing.get(0);
18938 if (DEBUG_PREFERRED) {
18939 Slog.i(TAG, "Checking replace of preferred:");
18940 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
18941 if (!cur.mPref.mAlways) {
18942 Slog.i(TAG, " -- CUR; not mAlways!");
18944 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch);
18945 Slog.i(TAG, " -- CUR: mSet="
18946 + Arrays.toString(cur.mPref.mSetComponents));
18947 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent);
18948 Slog.i(TAG, " -- NEW: mMatch="
18949 + (match&IntentFilter.MATCH_CATEGORY_MASK));
18950 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set));
18951 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString());
18954 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
18955 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
18956 && cur.mPref.sameSet(set)) {
18957 // Setting the preferred activity to what it happens to be already
18958 if (DEBUG_PREFERRED) {
18959 Slog.i(TAG, "Replacing with same preferred activity "
18960 + cur.mPref.mShortComponent + " for user "
18962 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
18967 if (existing != null) {
18968 if (DEBUG_PREFERRED) {
18969 Slog.i(TAG, existing.size() + " existing preferred matches for:");
18970 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
18972 for (int i = existing.size() - 1; i >= 0; --i) {
18973 final PreferredActivity pa = existing.get(i);
18974 if (DEBUG_PREFERRED) {
18975 Slog.i(TAG, "Removing existing preferred activity "
18976 + pa.mPref.mComponent + ":");
18977 pa.dump(new LogPrinter(Log.INFO, TAG), " ");
18979 pir.removeFilter(pa);
18984 addPreferredActivityInternal(filter, match, set, activity, true, userId,
18985 "Replacing preferred");
18989 public void clearPackagePreferredActivities(String packageName) {
18990 final int callingUid = Binder.getCallingUid();
18991 if (getInstantAppPackageName(callingUid) != null) {
18995 synchronized (mLock) {
18996 AndroidPackage pkg = mPackages.get(packageName);
18997 if (pkg == null || !isCallerSameApp(packageName, callingUid)) {
18998 if (mContext.checkCallingOrSelfPermission(
18999 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19000 != PackageManager.PERMISSION_GRANTED) {
19001 if (getUidTargetSdkVersionLockedLPr(callingUid)
19002 < Build.VERSION_CODES.FROYO) {
19003 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
19007 mContext.enforceCallingOrSelfPermission(
19008 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19011 final PackageSetting ps = mSettings.getPackageLPr(packageName);
19013 && shouldFilterApplicationLocked(
19014 ps, callingUid, UserHandle.getUserId(callingUid))) {
19018 int callingUserId = UserHandle.getCallingUserId();
19019 clearPackagePreferredActivities(packageName, callingUserId);
19022 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19023 private void clearPackagePreferredActivities(String packageName, int userId) {
19024 final SparseBooleanArray changedUsers = new SparseBooleanArray();
19026 clearPackagePreferredActivitiesLPw(packageName, changedUsers, userId);
19027 if (changedUsers.size() > 0) {
19028 updateDefaultHomeNotLocked(changedUsers);
19029 postPreferredActivityChangedBroadcast(userId);
19030 synchronized (mLock) {
19031 scheduleWritePackageRestrictionsLocked(userId);
19036 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19037 @GuardedBy("mLock")
19038 private void clearPackagePreferredActivitiesLPw(String packageName,
19039 @NonNull SparseBooleanArray outUserChanged, int userId) {
19040 ArrayList<PreferredActivity> removed = null;
19041 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19042 final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19043 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19044 if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19047 Iterator<PreferredActivity> it = pir.filterIterator();
19048 while (it.hasNext()) {
19049 PreferredActivity pa = it.next();
19050 // Mark entry for removal only if it matches the package name
19051 // and the entry is of type "always".
19052 if (packageName == null ||
19053 (pa.mPref.mComponent.getPackageName().equals(packageName)
19054 && pa.mPref.mAlways)) {
19055 if (removed == null) {
19056 removed = new ArrayList<>();
19061 if (removed != null) {
19062 for (int j=0; j<removed.size(); j++) {
19063 PreferredActivity pa = removed.get(j);
19064 pir.removeFilter(pa);
19066 outUserChanged.put(thisUserId, true);
19071 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19072 @GuardedBy("mLock")
19073 private void clearIntentFilterVerificationsLPw(int userId) {
19074 final int packageCount = mPackages.size();
19075 for (int i = 0; i < packageCount; i++) {
19076 AndroidPackage pkg = mPackages.valueAt(i);
19077 clearIntentFilterVerificationsLPw(pkg.getPackageName(), userId);
19081 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19082 @GuardedBy("mLock")
19083 void clearIntentFilterVerificationsLPw(String packageName, int userId) {
19084 if (userId == UserHandle.USER_ALL) {
19085 if (mSettings.removeIntentFilterVerificationLPw(packageName,
19086 mUserManager.getUserIds())) {
19087 for (int oneUserId : mUserManager.getUserIds()) {
19088 scheduleWritePackageRestrictionsLocked(oneUserId);
19092 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
19093 scheduleWritePackageRestrictionsLocked(userId);
19098 /** Clears state for all users, and touches intent filter verification policy */
19099 void clearDefaultBrowserIfNeeded(String packageName) {
19100 for (int oneUserId : mUserManager.getUserIds()) {
19101 clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
19105 private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
19106 final String defaultBrowserPackageName = mPermissionManager.getDefaultBrowser(userId);
19107 if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
19108 if (packageName.equals(defaultBrowserPackageName)) {
19109 mPermissionManager.setDefaultBrowser(null, true, true, userId);
19115 public void resetApplicationPreferences(int userId) {
19116 mContext.enforceCallingOrSelfPermission(
19117 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19118 final long identity = Binder.clearCallingIdentity();
19121 final SparseBooleanArray changedUsers = new SparseBooleanArray();
19122 clearPackagePreferredActivitiesLPw(null, changedUsers, userId);
19123 if (changedUsers.size() > 0) {
19124 postPreferredActivityChangedBroadcast(userId);
19126 synchronized (mLock) {
19127 mSettings.applyDefaultPreferredAppsLPw(userId);
19128 clearIntentFilterVerificationsLPw(userId);
19129 primeDomainVerificationsLPw(userId);
19131 mPermissionManager.resetAllRuntimePermissions(userId);
19132 updateDefaultHomeNotLocked(userId);
19133 // TODO: We have to reset the default SMS and Phone. This requires
19134 // significant refactoring to keep all default apps in the package
19135 // manager (cleaner but more work) or have the services provide
19136 // callbacks to the package manager to request a default app reset.
19137 mPermissionManager.setDefaultBrowser(null, true, true, userId);
19138 resetNetworkPolicies(userId);
19139 synchronized (mLock) {
19140 scheduleWritePackageRestrictionsLocked(userId);
19143 Binder.restoreCallingIdentity(identity);
19148 public int getPreferredActivities(List<IntentFilter> outFilters,
19149 List<ComponentName> outActivities, String packageName) {
19150 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19154 final int userId = UserHandle.getCallingUserId();
19156 synchronized (mLock) {
19157 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19159 final Iterator<PreferredActivity> it = pir.filterIterator();
19160 while (it.hasNext()) {
19161 final PreferredActivity pa = it.next();
19162 if (packageName == null
19163 || (pa.mPref.mComponent.getPackageName().equals(packageName)
19164 && pa.mPref.mAlways)) {
19165 if (outFilters != null) {
19166 outFilters.add(new IntentFilter(pa));
19168 if (outActivities != null) {
19169 outActivities.add(pa.mPref.mComponent);
19180 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19182 int callingUid = Binder.getCallingUid();
19183 if (callingUid != Process.SYSTEM_UID) {
19184 throw new SecurityException(
19185 "addPersistentPreferredActivity can only be run by the system");
19187 if (filter.countActions() == 0) {
19188 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19191 if (DEBUG_PREFERRED) {
19192 Slog.i(TAG, "Adding persistent preferred activity " + activity
19193 + " for user " + userId + ":");
19194 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
19196 synchronized (mLock) {
19197 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19198 new PersistentPreferredActivity(filter, activity));
19199 scheduleWritePackageRestrictionsLocked(userId);
19201 updateDefaultHomeNotLocked(userId);
19202 postPreferredActivityChangedBroadcast(userId);
19206 public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19207 int callingUid = Binder.getCallingUid();
19208 if (callingUid != Process.SYSTEM_UID) {
19209 throw new SecurityException(
19210 "clearPackagePersistentPreferredActivities can only be run by the system");
19212 ArrayList<PersistentPreferredActivity> removed = null;
19213 boolean changed = false;
19214 synchronized (mLock) {
19215 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19216 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19217 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19219 if (userId != thisUserId) {
19222 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19223 while (it.hasNext()) {
19224 PersistentPreferredActivity ppa = it.next();
19225 // Mark entry for removal only if it matches the package name.
19226 if (ppa.mComponent.getPackageName().equals(packageName)) {
19227 if (removed == null) {
19228 removed = new ArrayList<>();
19233 if (removed != null) {
19234 for (int j=0; j<removed.size(); j++) {
19235 PersistentPreferredActivity ppa = removed.get(j);
19236 ppir.removeFilter(ppa);
19243 updateDefaultHomeNotLocked(userId);
19244 postPreferredActivityChangedBroadcast(userId);
19245 synchronized (mLock) {
19246 scheduleWritePackageRestrictionsLocked(userId);
19252 * Common machinery for picking apart a restored XML blob and passing
19253 * it to a caller-supplied functor to be applied to the running system.
19255 private void restoreFromXml(XmlPullParser parser, int userId,
19256 String expectedStartTag, BlobXmlRestorer functor)
19257 throws IOException, XmlPullParserException {
19259 while ((type = parser.next()) != XmlPullParser.START_TAG
19260 && type != XmlPullParser.END_DOCUMENT) {
19262 if (type != XmlPullParser.START_TAG) {
19263 // oops didn't find a start tag?!
19264 if (DEBUG_BACKUP) {
19265 Slog.e(TAG, "Didn't find start tag during restore");
19269 // this is supposed to be TAG_PREFERRED_BACKUP
19270 if (!expectedStartTag.equals(parser.getName())) {
19271 if (DEBUG_BACKUP) {
19272 Slog.e(TAG, "Found unexpected tag " + parser.getName());
19277 // skip interfering stuff, then we're aligned with the backing implementation
19278 while ((type = parser.next()) == XmlPullParser.TEXT) { }
19279 functor.apply(parser, userId);
19282 private interface BlobXmlRestorer {
19283 void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19287 * Non-Binder method, support for the backup/restore mechanism: write the
19288 * full set of preferred activities in its canonical XML format. Returns the
19289 * XML output as a byte array, or null if there is none.
19292 public byte[] getPreferredActivityBackup(int userId) {
19293 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19294 throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19297 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19299 final XmlSerializer serializer = new FastXmlSerializer();
19300 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19301 serializer.startDocument(null, true);
19302 serializer.startTag(null, TAG_PREFERRED_BACKUP);
19304 synchronized (mLock) {
19305 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19308 serializer.endTag(null, TAG_PREFERRED_BACKUP);
19309 serializer.endDocument();
19310 serializer.flush();
19311 } catch (Exception e) {
19312 if (DEBUG_BACKUP) {
19313 Slog.e(TAG, "Unable to write preferred activities for backup", e);
19318 return dataStream.toByteArray();
19322 public void restorePreferredActivities(byte[] backup, int userId) {
19323 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19324 throw new SecurityException("Only the system may call restorePreferredActivities()");
19328 final XmlPullParser parser = Xml.newPullParser();
19329 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19330 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19331 (readParser, readUserId) -> {
19332 synchronized (mLock) {
19333 mSettings.readPreferredActivitiesLPw(readParser, readUserId);
19335 updateDefaultHomeNotLocked(readUserId);
19337 } catch (Exception e) {
19338 if (DEBUG_BACKUP) {
19339 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19345 * Non-Binder method, support for the backup/restore mechanism: write the
19346 * default browser (etc) settings in its canonical XML format. Returns the default
19347 * browser XML representation as a byte array, or null if there is none.
19350 public byte[] getDefaultAppsBackup(int userId) {
19351 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19352 throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19355 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19357 final XmlSerializer serializer = new FastXmlSerializer();
19358 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19359 serializer.startDocument(null, true);
19360 serializer.startTag(null, TAG_DEFAULT_APPS);
19362 synchronized (mLock) {
19363 mSettings.writeDefaultAppsLPr(serializer, userId);
19366 serializer.endTag(null, TAG_DEFAULT_APPS);
19367 serializer.endDocument();
19368 serializer.flush();
19369 } catch (Exception e) {
19370 if (DEBUG_BACKUP) {
19371 Slog.e(TAG, "Unable to write default apps for backup", e);
19376 return dataStream.toByteArray();
19380 public void restoreDefaultApps(byte[] backup, int userId) {
19381 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19382 throw new SecurityException("Only the system may call restoreDefaultApps()");
19386 final XmlPullParser parser = Xml.newPullParser();
19387 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19388 restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19389 (parser1, userId1) -> {
19390 final String defaultBrowser;
19391 synchronized (mLock) {
19392 mSettings.readDefaultAppsLPw(parser1, userId1);
19393 defaultBrowser = mSettings.removeDefaultBrowserPackageNameLPw(userId1);
19395 if (defaultBrowser != null) {
19397 .setDefaultBrowser(defaultBrowser, false, false, userId1);
19400 } catch (Exception e) {
19401 if (DEBUG_BACKUP) {
19402 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19408 public byte[] getIntentFilterVerificationBackup(int userId) {
19409 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19410 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19413 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19415 final XmlSerializer serializer = new FastXmlSerializer();
19416 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19417 serializer.startDocument(null, true);
19418 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19420 synchronized (mLock) {
19421 mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19424 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19425 serializer.endDocument();
19426 serializer.flush();
19427 } catch (Exception e) {
19428 if (DEBUG_BACKUP) {
19429 Slog.e(TAG, "Unable to write default apps for backup", e);
19434 return dataStream.toByteArray();
19438 public void restoreIntentFilterVerification(byte[] backup, int userId) {
19439 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19440 throw new SecurityException("Only the system may call restorePreferredActivities()");
19444 final XmlPullParser parser = Xml.newPullParser();
19445 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19446 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19447 (parser1, userId1) -> {
19448 synchronized (mLock) {
19449 mSettings.readAllDomainVerificationsLPr(parser1, userId1);
19450 mSettings.writeLPr();
19453 } catch (Exception e) {
19454 if (DEBUG_BACKUP) {
19455 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19461 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
19462 int sourceUserId, int targetUserId, int flags) {
19463 mContext.enforceCallingOrSelfPermission(
19464 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19465 int callingUid = Binder.getCallingUid();
19466 enforceOwnerRights(ownerPackage, callingUid);
19467 PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
19468 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19469 if (intentFilter.countActions() == 0) {
19470 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
19473 synchronized (mLock) {
19474 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
19475 ownerPackage, targetUserId, flags);
19476 CrossProfileIntentResolver resolver =
19477 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19478 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
19479 // We have all those whose filter is equal. Now checking if the rest is equal as well.
19480 if (existing != null) {
19481 int size = existing.size();
19482 for (int i = 0; i < size; i++) {
19483 if (newFilter.equalsIgnoreFilter(existing.get(i))) {
19488 resolver.addFilter(newFilter);
19489 scheduleWritePackageRestrictionsLocked(sourceUserId);
19494 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
19495 mContext.enforceCallingOrSelfPermission(
19496 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19497 final int callingUid = Binder.getCallingUid();
19498 enforceOwnerRights(ownerPackage, callingUid);
19499 PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
19500 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19501 synchronized (mLock) {
19502 CrossProfileIntentResolver resolver =
19503 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19504 ArraySet<CrossProfileIntentFilter> set =
19505 new ArraySet<>(resolver.filterSet());
19506 for (CrossProfileIntentFilter filter : set) {
19507 if (filter.getOwnerPackage().equals(ownerPackage)) {
19508 resolver.removeFilter(filter);
19511 scheduleWritePackageRestrictionsLocked(sourceUserId);
19515 // Enforcing that callingUid is owning pkg on userId
19516 private void enforceOwnerRights(String pkg, int callingUid) {
19517 // The system owns everything.
19518 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19521 final int callingUserId = UserHandle.getUserId(callingUid);
19522 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
19524 throw new IllegalArgumentException("Unknown package " + pkg + " on user "
19527 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
19528 throw new SecurityException("Calling uid " + callingUid
19529 + " does not own package " + pkg);
19534 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
19535 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19538 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
19542 * Send a {@code PackageInstaller.ACTION_SESSION_UPDATED} broadcast intent, containing
19543 * the {@code sessionInfo} in the extra field {@code PackageInstaller.EXTRA_SESSION}.
19545 public void sendSessionUpdatedBroadcast(PackageInstaller.SessionInfo sessionInfo,
19547 if (TextUtils.isEmpty(sessionInfo.installerPackageName)) {
19550 Intent sessionUpdatedIntent = new Intent(PackageInstaller.ACTION_SESSION_UPDATED)
19551 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
19552 .setPackage(sessionInfo.installerPackageName);
19553 mContext.sendBroadcastAsUser(sessionUpdatedIntent, UserHandle.of(userId));
19556 public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
19557 UserManagerService ums = UserManagerService.getInstance();
19558 if (ums != null && !sessionInfo.isStaged()) {
19559 final UserInfo parent = ums.getProfileParent(userId);
19560 final int launcherUid = (parent != null) ? parent.id : userId;
19561 final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
19562 if (launcherComponent != null) {
19563 Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
19564 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
19565 .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
19566 .setPackage(launcherComponent.getPackageName());
19567 mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
19569 // TODO(b/122900055) Change/Remove this and replace with new permission role.
19570 if (mAppPredictionServicePackage != null) {
19571 Intent predictorIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
19572 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
19573 .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
19574 .setPackage(mAppPredictionServicePackage);
19575 mContext.sendBroadcastAsUser(predictorIntent, UserHandle.of(launcherUid));
19581 * Report the 'Home' activity which is currently set as "always use this one". If non is set
19582 * then reports the most likely home activity or null if there are more than one.
19584 private ComponentName getDefaultHomeActivity(int userId) {
19585 List<ResolveInfo> allHomeCandidates = new ArrayList<>();
19586 ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
19591 // Find the launcher with the highest priority and return that component if there are no
19592 // other home activity with the same priority.
19593 int lastPriority = Integer.MIN_VALUE;
19594 ComponentName lastComponent = null;
19595 final int size = allHomeCandidates.size();
19596 for (int i = 0; i < size; i++) {
19597 final ResolveInfo ri = allHomeCandidates.get(i);
19598 if (ri.priority > lastPriority) {
19599 lastComponent = ri.activityInfo.getComponentName();
19600 lastPriority = ri.priority;
19601 } else if (ri.priority == lastPriority) {
19602 // Two components found with same priority.
19603 lastComponent = null;
19606 return lastComponent;
19609 private Intent getHomeIntent() {
19610 Intent intent = new Intent(Intent.ACTION_MAIN);
19611 intent.addCategory(Intent.CATEGORY_HOME);
19612 intent.addCategory(Intent.CATEGORY_DEFAULT);
19616 private IntentFilter getHomeFilter() {
19617 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
19618 filter.addCategory(Intent.CATEGORY_HOME);
19619 filter.addCategory(Intent.CATEGORY_DEFAULT);
19623 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
19625 Intent intent = getHomeIntent();
19626 List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
19627 PackageManager.GET_META_DATA, userId);
19628 allHomeCandidates.clear();
19629 if (resolveInfos == null) {
19632 allHomeCandidates.addAll(resolveInfos);
19634 final String packageName = mPermissionManager.getDefaultHome(userId);
19635 if (packageName == null) {
19638 int resolveInfosSize = resolveInfos.size();
19639 for (int i = 0; i < resolveInfosSize; i++) {
19640 ResolveInfo resolveInfo = resolveInfos.get(i);
19642 if (resolveInfo.activityInfo != null && TextUtils.equals(
19643 resolveInfo.activityInfo.packageName, packageName)) {
19644 return new ComponentName(resolveInfo.activityInfo.packageName,
19645 resolveInfo.activityInfo.name);
19651 /** <b>must not hold {@link #mLock}</b> */
19652 private void updateDefaultHomeNotLocked(SparseBooleanArray userIds) {
19653 if (Thread.holdsLock(mLock)) {
19654 Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
19655 + " is holding mLock", new Throwable());
19657 for (int i = userIds.size() - 1; i >= 0; --i) {
19658 final int userId = userIds.keyAt(i);
19659 updateDefaultHomeNotLocked(userId);
19664 * <b>must not hold {@link #mLock}</b>
19666 * @return Whether the ACTION_PREFERRED_ACTIVITY_CHANGED broadcast has been scheduled.
19668 private boolean updateDefaultHomeNotLocked(int userId) {
19669 if (Thread.holdsLock(mLock)) {
19670 Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
19671 + " is holding mLock", new Throwable());
19673 if (!mSystemReady) {
19674 // We might get called before system is ready because of package changes etc, but
19675 // finding preferred activity depends on settings provider, so we ignore the update
19679 final Intent intent = getHomeIntent();
19680 final List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
19681 PackageManager.GET_META_DATA, userId);
19682 final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(
19683 intent, null, 0, resolveInfos, 0, true, false, false, userId);
19684 final String packageName = preferredResolveInfo != null
19685 && preferredResolveInfo.activityInfo != null
19686 ? preferredResolveInfo.activityInfo.packageName : null;
19687 final String currentPackageName = mPermissionManager.getDefaultHome(userId);
19688 if (TextUtils.equals(currentPackageName, packageName)) {
19691 final String[] callingPackages = getPackagesForUid(Binder.getCallingUid());
19692 if (callingPackages != null && ArrayUtils.contains(callingPackages,
19693 mRequiredPermissionControllerPackage)) {
19694 // PermissionController manages default home directly.
19697 mPermissionManager.setDefaultHome(packageName, userId, (successful) -> {
19699 postPreferredActivityChangedBroadcast(userId);
19706 public void setHomeActivity(ComponentName comp, int userId) {
19707 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19710 ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
19711 getHomeActivitiesAsUser(homeActivities, userId);
19713 boolean found = false;
19715 final int size = homeActivities.size();
19716 final ComponentName[] set = new ComponentName[size];
19717 for (int i = 0; i < size; i++) {
19718 final ResolveInfo candidate = homeActivities.get(i);
19719 final ActivityInfo info = candidate.activityInfo;
19720 final ComponentName activityName = new ComponentName(info.packageName, info.name);
19721 set[i] = activityName;
19722 if (!found && activityName.equals(comp)) {
19727 throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
19730 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
19731 set, comp, userId);
19734 private @Nullable String getSetupWizardPackageNameImpl() {
19735 final Intent intent = new Intent(Intent.ACTION_MAIN);
19736 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
19738 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19739 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19740 | MATCH_DISABLED_COMPONENTS,
19741 UserHandle.myUserId());
19742 if (matches.size() == 1) {
19743 return matches.get(0).getComponentInfo().packageName;
19745 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
19746 + ": matches=" + matches);
19751 private @Nullable String getStorageManagerPackageName() {
19752 final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
19754 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19755 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19756 | MATCH_DISABLED_COMPONENTS,
19757 UserHandle.myUserId());
19758 if (matches.size() == 1) {
19759 return matches.get(0).getComponentInfo().packageName;
19761 Slog.e(TAG, "There should probably be exactly one storage manager; found "
19762 + matches.size() + ": matches=" + matches);
19768 public String getDefaultTextClassifierPackageName() {
19769 return ensureSystemPackageName(
19770 mContext.getString(R.string.config_servicesExtensionPackage));
19774 public String getSystemTextClassifierPackageName() {
19775 return ensureSystemPackageName(
19776 mContext.getString(R.string.config_defaultTextClassifierPackage));
19780 public @Nullable String getAttentionServicePackageName() {
19781 final String flattenedComponentName =
19782 mContext.getString(R.string.config_defaultAttentionService);
19783 if (flattenedComponentName != null) {
19784 ComponentName componentName = ComponentName.unflattenFromString(flattenedComponentName);
19785 if (componentName != null && componentName.getPackageName() != null) {
19786 return ensureSystemPackageName(componentName.getPackageName());
19792 private @Nullable String getDocumenterPackageName() {
19793 final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
19794 intent.addCategory(Intent.CATEGORY_OPENABLE);
19795 intent.setType("*/*");
19796 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
19798 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, resolvedType,
19799 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19800 | MATCH_DISABLED_COMPONENTS,
19801 UserHandle.myUserId());
19802 if (matches.size() == 1) {
19803 return matches.get(0).getComponentInfo().packageName;
19805 Slog.e(TAG, "There should probably be exactly one documenter; found "
19806 + matches.size() + ": matches=" + matches);
19812 private String getDeviceConfiguratorPackageName() {
19813 return ensureSystemPackageName(mContext.getString(
19814 R.string.config_deviceConfiguratorPackageName));
19818 public String getWellbeingPackageName() {
19819 return ensureSystemPackageName(mContext.getString(R.string.config_defaultWellbeingPackage));
19823 public String getAppPredictionServicePackageName() {
19824 String flattenedAppPredictionServiceComponentName =
19825 mContext.getString(R.string.config_defaultAppPredictionService);
19826 if (flattenedAppPredictionServiceComponentName == null) {
19829 ComponentName appPredictionServiceComponentName =
19830 ComponentName.unflattenFromString(flattenedAppPredictionServiceComponentName);
19831 if (appPredictionServiceComponentName == null) {
19834 return ensureSystemPackageName(appPredictionServiceComponentName.getPackageName());
19837 private @NonNull String[] dropNonSystemPackages(@NonNull String[] pkgNames) {
19838 return emptyIfNull(filter(pkgNames, String[]::new, mIsSystemPackage), String.class);
19841 private Predicate<String> mIsSystemPackage = (pkgName) -> {
19842 if ("android".equals(pkgName)) {
19845 AndroidPackage pkg = mPackages.get(pkgName);
19846 return pkg != null && pkg.isSystem();
19850 public String getSystemCaptionsServicePackageName() {
19851 String flattenedSystemCaptionsServiceComponentName =
19852 mContext.getString(R.string.config_defaultSystemCaptionsService);
19854 if (TextUtils.isEmpty(flattenedSystemCaptionsServiceComponentName)) {
19858 ComponentName systemCaptionsServiceComponentName =
19859 ComponentName.unflattenFromString(flattenedSystemCaptionsServiceComponentName);
19860 if (systemCaptionsServiceComponentName == null) {
19863 return ensureSystemPackageName(systemCaptionsServiceComponentName.getPackageName());
19867 public String getSetupWizardPackageName() {
19868 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19869 throw new SecurityException("Non-system caller");
19871 return mPmInternal.getSetupWizardPackageName();
19874 public String getIncidentReportApproverPackageName() {
19875 return ensureSystemPackageName(mContext.getString(
19876 R.string.config_incidentReportApproverPackage));
19880 public String[] getTelephonyPackageNames() {
19881 String names = mContext.getString(R.string.config_telephonyPackages);
19882 String[] telephonyPackageNames = null;
19883 if (!TextUtils.isEmpty(names)) {
19884 telephonyPackageNames = names.trim().split(",");
19886 return ensureSystemPackageNames(telephonyPackageNames);
19890 public String getContentCaptureServicePackageName() {
19891 final String flattenedContentCaptureService =
19892 mContext.getString(R.string.config_defaultContentCaptureService);
19894 if (TextUtils.isEmpty(flattenedContentCaptureService)) {
19898 final ComponentName contentCaptureServiceComponentName =
19899 ComponentName.unflattenFromString(flattenedContentCaptureService);
19900 if (contentCaptureServiceComponentName == null) {
19903 return ensureSystemPackageName(contentCaptureServiceComponentName.getPackageName());
19907 private String getRetailDemoPackageName() {
19908 final String predefinedPkgName = mContext.getString(R.string.config_retailDemoPackage);
19909 final String predefinedSignature = mContext.getString(
19910 R.string.config_retailDemoPackageSignature);
19912 if (TextUtils.isEmpty(predefinedPkgName) || TextUtils.isEmpty(predefinedSignature)) {
19916 final AndroidPackage androidPkg = mPackages.get(predefinedPkgName);
19917 if (androidPkg != null) {
19918 final SigningDetails signingDetail = androidPkg.getSigningDetails();
19919 if (signingDetail != null && signingDetail.signatures != null) {
19921 final MessageDigest msgDigest = MessageDigest.getInstance("SHA-256");
19922 for (Signature signature : signingDetail.signatures) {
19923 if (TextUtils.equals(predefinedSignature,
19924 HexEncoding.encodeToString(msgDigest.digest(
19925 signature.toByteArray()), false))) {
19926 return predefinedPkgName;
19929 } catch (NoSuchAlgorithmException e) {
19932 "Unable to verify signatures as getting the retail demo package name",
19942 private String ensureSystemPackageName(@Nullable String packageName) {
19943 if (packageName == null) {
19946 long token = Binder.clearCallingIdentity();
19948 if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) {
19952 Binder.restoreCallingIdentity(token);
19954 return packageName;
19958 private String[] ensureSystemPackageNames(@Nullable String[] packageNames) {
19959 if (packageNames == null) {
19962 final int packageNamesLength = packageNames.length;
19963 for (int i = 0; i < packageNamesLength; i++) {
19964 packageNames[i] = ensureSystemPackageName(packageNames[i]);
19966 return ArrayUtils.filterNotNull(packageNames, String[]::new);
19970 public void setApplicationEnabledSetting(String appPackageName,
19971 int newState, int flags, int userId, String callingPackage) {
19972 if (!mUserManager.exists(userId)) return;
19973 if (callingPackage == null) {
19974 callingPackage = Integer.toString(Binder.getCallingUid());
19976 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
19980 public void setUpdateAvailable(String packageName, boolean updateAvailable) {
19981 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
19982 synchronized (mLock) {
19983 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
19984 if (pkgSetting != null) {
19985 pkgSetting.setUpdateAvailable(updateAvailable);
19991 public void setComponentEnabledSetting(ComponentName componentName,
19992 int newState, int flags, int userId) {
19993 if (!mUserManager.exists(userId)) return;
19994 setEnabledSetting(componentName.getPackageName(),
19995 componentName.getClassName(), newState, flags, userId, null);
19998 private void setEnabledSetting(final String packageName, String className, int newState,
19999 final int flags, int userId, String callingPackage) {
20000 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
20001 || newState == COMPONENT_ENABLED_STATE_ENABLED
20002 || newState == COMPONENT_ENABLED_STATE_DISABLED
20003 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20004 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
20005 throw new IllegalArgumentException("Invalid new component state: "
20008 PackageSetting pkgSetting;
20009 final int callingUid = Binder.getCallingUid();
20010 final int permission;
20011 if (callingUid == Process.SYSTEM_UID) {
20012 permission = PackageManager.PERMISSION_GRANTED;
20014 permission = mContext.checkCallingOrSelfPermission(
20015 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20017 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20018 false /* requireFullPermission */, true /* checkShell */, "set enabled");
20019 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20020 boolean sendNow = false;
20021 boolean isApp = (className == null);
20022 final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
20023 String componentName = isApp ? packageName : className;
20024 ArrayList<String> components;
20027 synchronized (mLock) {
20028 pkgSetting = mSettings.mPackages.get(packageName);
20029 if (pkgSetting == null) {
20030 if (!isCallerInstantApp) {
20031 if (className == null) {
20032 throw new IllegalArgumentException("Unknown package: " + packageName);
20034 throw new IllegalArgumentException(
20035 "Unknown component: " + packageName + "/" + className);
20037 // throw SecurityException to prevent leaking package information
20038 throw new SecurityException(
20039 "Attempt to change component state; "
20040 + "pid=" + Binder.getCallingPid()
20041 + ", uid=" + callingUid
20042 + (className == null
20043 ? ", package=" + packageName
20044 : ", component=" + packageName + "/" + className));
20049 // Limit who can change which apps
20050 if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
20051 // Don't allow apps that don't have permission to modify other apps
20052 if (!allowedByPermission
20053 || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
20054 throw new SecurityException(
20055 "Attempt to change component state; "
20056 + "pid=" + Binder.getCallingPid()
20057 + ", uid=" + callingUid
20058 + (className == null
20059 ? ", package=" + packageName
20060 : ", component=" + packageName + "/" + className));
20062 // Don't allow changing protected packages.
20063 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20064 throw new SecurityException("Cannot disable a protected package: " + packageName);
20067 // Only allow apps with CHANGE_COMPONENT_ENABLED_STATE permission to change hidden
20068 // app details activity
20069 if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)
20070 && !allowedByPermission) {
20071 throw new SecurityException("Cannot disable a system-generated component");
20074 synchronized (mLock) {
20075 if (callingUid == Process.SHELL_UID
20076 && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20077 // Shell can only change whole packages between ENABLED and DISABLED_USER states
20078 // unless it is a test package.
20079 int oldState = pkgSetting.getEnabled(userId);
20080 if (className == null
20082 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20083 || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20084 || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20086 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20087 || newState == COMPONENT_ENABLED_STATE_DEFAULT
20088 || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20091 throw new SecurityException(
20092 "Shell cannot change component state for " + packageName + "/"
20093 + className + " to " + newState);
20097 if (className == null) {
20098 // We're dealing with an application/package level state change
20099 synchronized (mLock) {
20100 if (pkgSetting.getEnabled(userId) == newState) {
20105 // If we're enabling a system stub, there's a little more work to do.
20106 // Prior to enabling the package, we need to decompress the APK(s) to the
20107 // data partition and then replace the version on the system partition.
20108 final AndroidPackage deletedPkg = pkgSetting.pkg;
20109 final boolean isSystemStub = deletedPkg.isStub()
20110 && deletedPkg.isSystem();
20112 && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20113 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
20114 if (!enableCompressedPackage(deletedPkg, pkgSetting)) {
20118 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20119 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20120 // Don't care about who enables an app.
20121 callingPackage = null;
20123 synchronized (mLock) {
20124 pkgSetting.setEnabled(newState, userId, callingPackage);
20125 if (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20126 || newState == COMPONENT_ENABLED_STATE_DISABLED
20127 && pkgSetting.getPermissionsState().hasPermission(
20128 Manifest.permission.SUSPEND_APPS, userId)) {
20129 // This app should not generally be allowed to get disabled by the UI, but if it
20130 // ever does, we don't want to end up with some of the user's apps permanently
20132 unsuspendForSuspendingPackage(packageName, userId);
20133 removeAllDistractingPackageRestrictions(userId);
20137 synchronized (mLock) {
20138 // We're dealing with a component level state change
20139 // First, verify that this is a valid class name.
20140 AndroidPackage pkg = pkgSetting.pkg;
20141 if (pkg == null || !AndroidPackageUtils.hasComponentClassName(pkg, className)) {
20143 pkg.getTargetSdkVersion() >=
20144 Build.VERSION_CODES.JELLY_BEAN) {
20145 throw new IllegalArgumentException("Component class " + className
20146 + " does not exist in " + packageName);
20148 Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20149 + className + " does not exist in " + packageName);
20152 switch (newState) {
20153 case COMPONENT_ENABLED_STATE_ENABLED:
20154 if (!pkgSetting.enableComponentLPw(className, userId)) {
20158 case COMPONENT_ENABLED_STATE_DISABLED:
20159 if (!pkgSetting.disableComponentLPw(className, userId)) {
20163 case COMPONENT_ENABLED_STATE_DEFAULT:
20164 if (!pkgSetting.restoreComponentLPw(className, userId)) {
20169 Slog.e(TAG, "Invalid new component state: " + newState);
20174 synchronized (mLock) {
20175 if ((flags & PackageManager.SYNCHRONOUS) != 0) {
20176 flushPackageRestrictionsAsUserInternalLocked(userId);
20178 scheduleWritePackageRestrictionsLocked(userId);
20180 updateSequenceNumberLP(pkgSetting, new int[] { userId });
20181 final long callingId = Binder.clearCallingIdentity();
20183 updateInstantAppInstallerLocked(packageName);
20185 Binder.restoreCallingIdentity(callingId);
20187 components = mPendingBroadcasts.get(userId, packageName);
20188 final boolean newPackage = components == null;
20190 components = new ArrayList<>();
20192 if (!components.contains(componentName)) {
20193 components.add(componentName);
20195 if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20197 // Purge entry from pending broadcast list if another one exists already
20198 // since we are sending one right away.
20199 mPendingBroadcasts.remove(userId, packageName);
20202 mPendingBroadcasts.put(userId, packageName, components);
20204 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20205 // Schedule a message - if it has been a "reasonably long time" since the
20206 // service started, send the broadcast with a delay of one second to avoid
20207 // delayed reactions from the receiver, else keep the default ten second delay
20208 // to avoid extreme thrashing on service startup.
20209 final long broadcastDelay = SystemClock.uptimeMillis() > mServiceStartWithDelay
20211 : BROADCAST_DELAY_DURING_STARTUP;
20212 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, broadcastDelay);
20217 long callingId = Binder.clearCallingIdentity();
20220 int packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20221 sendPackageChangedBroadcast(packageName,
20222 (flags & PackageManager.DONT_KILL_APP) != 0, components, packageUid, null);
20225 Binder.restoreCallingIdentity(callingId);
20231 public void flushPackageRestrictionsAsUser(int userId) {
20232 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20235 if (!mUserManager.exists(userId)) {
20238 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20239 false /* checkShell */, "flushPackageRestrictions");
20240 synchronized (mLock) {
20241 flushPackageRestrictionsAsUserInternalLocked(userId);
20245 @GuardedBy("mLock")
20246 private void flushPackageRestrictionsAsUserInternalLocked(int userId) {
20247 // NOTE: this invokes synchronous disk access, so callers using this
20248 // method should consider running on a background thread
20249 mSettings.writePackageRestrictionsLPr(userId);
20250 mDirtyUsers.remove(userId);
20251 if (mDirtyUsers.isEmpty()) {
20252 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20256 private void sendPackageChangedBroadcast(String packageName,
20257 boolean dontKillApp, ArrayList<String> componentNames, int packageUid,
20260 Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20262 Bundle extras = new Bundle(4);
20263 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20264 String nameList[] = new String[componentNames.size()];
20265 componentNames.toArray(nameList);
20266 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
20267 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, dontKillApp);
20268 extras.putInt(Intent.EXTRA_UID, packageUid);
20269 if (reason != null) {
20270 extras.putString(Intent.EXTRA_REASON, reason);
20272 // If this is not reporting a change of the overall package, then only send it
20273 // to registered receivers. We don't want to launch a swath of apps for every
20274 // little component state change.
20275 final int flags = !componentNames.contains(packageName)
20276 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
20277 final int userId = UserHandle.getUserId(packageUid);
20278 final boolean isInstantApp = isInstantApp(packageName, userId);
20279 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
20280 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
20281 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null,
20282 userIds, instantUserIds);
20286 public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
20287 if (!mUserManager.exists(userId)) return;
20288 final int callingUid = Binder.getCallingUid();
20289 if (getInstantAppPackageName(callingUid) != null) {
20292 final int permission = mContext.checkCallingOrSelfPermission(
20293 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20294 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20295 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20296 true /* requireFullPermission */, true /* checkShell */, "stop package");
20298 synchronized (mLock) {
20299 final PackageSetting ps = mSettings.mPackages.get(packageName);
20300 if (!shouldFilterApplicationLocked(ps, callingUid, userId)
20301 && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
20302 allowedByPermission, callingUid, userId)) {
20303 scheduleWritePackageRestrictionsLocked(userId);
20309 public String getInstallerPackageName(String packageName) {
20310 final int callingUid = Binder.getCallingUid();
20311 synchronized (mLock) {
20312 final InstallSource installSource = getInstallSourceLocked(packageName, callingUid);
20313 if (installSource == null) {
20314 throw new IllegalArgumentException("Unknown package: " + packageName);
20316 String installerPackageName = installSource.installerPackageName;
20317 if (installerPackageName != null) {
20318 final PackageSetting ps = mSettings.mPackages.get(installerPackageName);
20319 if (ps == null || shouldFilterApplicationLocked(ps, callingUid,
20320 UserHandle.getUserId(callingUid))) {
20321 installerPackageName = null;
20324 return installerPackageName;
20330 public InstallSourceInfo getInstallSourceInfo(String packageName) {
20331 final int callingUid = Binder.getCallingUid();
20332 final int userId = UserHandle.getUserId(callingUid);
20334 String installerPackageName;
20335 String initiatingPackageName;
20336 String originatingPackageName;
20338 final InstallSource installSource;
20339 synchronized (mLock) {
20340 installSource = getInstallSourceLocked(packageName, callingUid);
20341 if (installSource == null) {
20345 installerPackageName = installSource.installerPackageName;
20346 if (installerPackageName != null) {
20347 final PackageSetting ps = mSettings.mPackages.get(installerPackageName);
20348 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
20349 installerPackageName = null;
20353 if (installSource.isInitiatingPackageUninstalled) {
20354 // We can't check visibility in the usual way, since the initiating package is no
20355 // longer present. So we apply simpler rules to whether to expose the info:
20356 // 1. Instant apps can't see it.
20357 // 2. Otherwise only the installed app itself can see it.
20358 final boolean isInstantApp = getInstantAppPackageName(callingUid) != null;
20359 if (!isInstantApp && isCallerSameApp(packageName, callingUid)) {
20360 initiatingPackageName = installSource.initiatingPackageName;
20362 initiatingPackageName = null;
20365 // All installSource strings are interned, so == is ok here
20366 if (installSource.initiatingPackageName == installSource.installerPackageName) {
20367 // The installer and initiator will often be the same, and when they are
20368 // we can skip doing the same check again.
20369 initiatingPackageName = installerPackageName;
20371 initiatingPackageName = installSource.initiatingPackageName;
20372 final PackageSetting ps = mSettings.mPackages.get(initiatingPackageName);
20373 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
20374 initiatingPackageName = null;
20379 originatingPackageName = installSource.originatingPackageName;
20380 if (originatingPackageName != null) {
20381 final PackageSetting ps = mSettings.mPackages.get(originatingPackageName);
20382 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
20383 originatingPackageName = null;
20388 // Remaining work can safely be done outside the lock. (Note that installSource is
20389 // immutable so it's ok to carry on reading from it.)
20391 if (originatingPackageName != null && mContext.checkCallingOrSelfPermission(
20392 Manifest.permission.INSTALL_PACKAGES) != PackageManager.PERMISSION_GRANTED) {
20393 originatingPackageName = null;
20396 // If you can see the initiatingPackageName, and we have valid signing info for it,
20397 // then we let you see that too.
20398 final SigningInfo initiatingPackageSigningInfo;
20399 final PackageSignatures signatures = installSource.initiatingPackageSignatures;
20400 if (initiatingPackageName != null && signatures != null
20401 && signatures.mSigningDetails != SigningDetails.UNKNOWN) {
20402 initiatingPackageSigningInfo = new SigningInfo(signatures.mSigningDetails);
20404 initiatingPackageSigningInfo = null;
20407 return new InstallSourceInfo(initiatingPackageName, initiatingPackageSigningInfo,
20408 originatingPackageName, installerPackageName);
20411 @GuardedBy("mLock")
20413 private InstallSource getInstallSourceLocked(String packageName, int callingUid) {
20414 final PackageSetting ps = mSettings.mPackages.get(packageName);
20416 // Installer info for Apex is not stored in PackageManager
20417 if (ps == null && mApexManager.isApexPackage(packageName)) {
20418 return InstallSource.EMPTY;
20421 if (ps == null || shouldFilterApplicationLocked(ps, callingUid,
20422 UserHandle.getUserId(callingUid))) {
20426 return ps.installSource;
20429 public boolean isOrphaned(String packageName) {
20431 synchronized (mLock) {
20432 if (!mPackages.containsKey(packageName)) {
20435 return mSettings.isOrphaned(packageName);
20440 public int getApplicationEnabledSetting(String packageName, int userId) {
20441 if (!mUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20442 int callingUid = Binder.getCallingUid();
20443 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20444 false /* requireFullPermission */, false /* checkShell */, "get enabled");
20446 synchronized (mLock) {
20447 if (shouldFilterApplicationLocked(
20448 mSettings.getPackageLPr(packageName), callingUid, userId)) {
20449 return COMPONENT_ENABLED_STATE_DISABLED;
20451 return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20456 public int getComponentEnabledSetting(@NonNull ComponentName component, int userId) {
20457 if (component == null) return COMPONENT_ENABLED_STATE_DEFAULT;
20458 if (!mUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20459 int callingUid = Binder.getCallingUid();
20460 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20461 false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
20462 synchronized (mLock) {
20463 if (shouldFilterApplicationLocked(
20464 mSettings.getPackageLPr(component.getPackageName()), callingUid,
20465 component, TYPE_UNKNOWN, userId)) {
20466 return COMPONENT_ENABLED_STATE_DISABLED;
20468 return mSettings.getComponentEnabledSettingLPr(component, userId);
20473 public void enterSafeMode() {
20474 enforceSystemOrRoot("Only the system can request entering safe mode");
20476 if (!mSystemReady) {
20482 public void systemReady() {
20483 enforceSystemOrRoot("Only the system can claim the system is ready");
20485 mSystemReady = true;
20486 final ContentResolver resolver = mContext.getContentResolver();
20487 ContentObserver co = new ContentObserver(mHandler) {
20489 public void onChange(boolean selfChange) {
20490 final boolean ephemeralFeatureDisabled =
20491 Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0;
20492 for (int userId : UserManagerService.getInstance().getUserIds()) {
20493 final boolean instantAppsDisabledForUser =
20494 ephemeralFeatureDisabled || Secure.getIntForUser(resolver,
20495 Secure.INSTANT_APPS_ENABLED, 1, userId) == 0;
20496 mWebInstantAppsDisabled.put(userId, instantAppsDisabledForUser);
20500 mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20501 .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20502 false, co, UserHandle.USER_ALL);
20503 mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure
20504 .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL);
20507 mAppsFilter.onSystemReady();
20509 // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20510 // disabled after already being started.
20511 CarrierAppUtils.disableCarrierAppsUntilPrivileged(
20512 mContext.getOpPackageName(), UserHandle.USER_SYSTEM, mContext);
20514 disableSkuSpecificApps();
20516 // Read the compatibilty setting when the system is ready.
20517 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20518 mContext.getContentResolver(),
20519 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20520 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20522 if (DEBUG_SETTINGS) {
20523 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20526 synchronized (mLock) {
20527 // Verify that all of the preferred activity components actually
20528 // exist. It is possible for applications to be updated and at
20529 // that point remove a previously declared activity component that
20530 // had been set as a preferred activity. We try to clean this up
20531 // the next time we encounter that preferred activity, but it is
20532 // possible for the user flow to never be able to return to that
20533 // situation so here we do a sanity check to make sure we haven't
20534 // left any junk around.
20535 ArrayList<PreferredActivity> removed = new ArrayList<>();
20536 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20537 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20539 for (PreferredActivity pa : pir.filterSet()) {
20540 if (!mComponentResolver.isActivityDefined(pa.mPref.mComponent)) {
20544 if (removed.size() > 0) {
20545 for (int r=0; r<removed.size(); r++) {
20546 PreferredActivity pa = removed.get(r);
20547 Slog.w(TAG, "Removing dangling preferred activity: "
20548 + pa.mPref.mComponent);
20549 pir.removeFilter(pa);
20551 mSettings.writePackageRestrictionsLPr(
20552 mSettings.mPreferredActivities.keyAt(i));
20557 mUserManager.systemReady();
20559 // Now that we've scanned all packages, and granted any default
20560 // permissions, ensure permissions are updated. Beware of dragons if you
20561 // try optimizing this.
20562 synchronized (mLock) {
20563 mPermissionManager.updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, false);
20565 final PermissionPolicyInternal permissionPolicyInternal =
20566 mInjector.getPermissionPolicyInternal();
20567 permissionPolicyInternal.setOnInitializedCallback(userId -> {
20568 // The SDK updated case is already handled when we run during the ctor.
20569 synchronized (mLock) {
20570 mPermissionManager.updateAllPermissions(
20571 StorageManager.UUID_PRIVATE_INTERNAL, false);
20576 // Watch for external volumes that come and go over time
20577 final StorageManager storage = mInjector.getStorageManager();
20578 storage.registerListener(mStorageListener);
20580 mInstallerService.systemReady();
20581 mApexManager.systemReady(mContext);
20582 mPackageDexOptimizer.systemReady();
20584 mInjector.getStorageManagerInternal().addExternalStoragePolicy(
20585 new StorageManagerInternal.ExternalStorageMountPolicy() {
20587 public int getMountMode(int uid, String packageName) {
20588 if (Process.isIsolated(uid)) {
20589 return Zygote.MOUNT_EXTERNAL_NONE;
20591 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20592 return Zygote.MOUNT_EXTERNAL_DEFAULT;
20594 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20595 return Zygote.MOUNT_EXTERNAL_READ;
20597 return Zygote.MOUNT_EXTERNAL_WRITE;
20601 public boolean hasExternalStorage(int uid, String packageName) {
20606 // Now that we're mostly running, clean up stale users and apps
20607 mUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20608 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20610 mPermissionManager.systemReady();
20612 if (mInstantAppResolverConnection != null) {
20613 mContext.registerReceiver(new BroadcastReceiver() {
20615 public void onReceive(Context context, Intent intent) {
20616 mInstantAppResolverConnection.optimisticBind();
20617 mContext.unregisterReceiver(this);
20619 }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
20622 IntentFilter overlayFilter = new IntentFilter(Intent.ACTION_OVERLAY_CHANGED);
20623 overlayFilter.addDataScheme("package");
20624 mContext.registerReceiver(new BroadcastReceiver() {
20626 public void onReceive(Context context, Intent intent) {
20627 if (intent == null) {
20630 Uri data = intent.getData();
20631 if (data == null) {
20634 String packageName = data.getSchemeSpecificPart();
20635 if (packageName == null) {
20638 AndroidPackage pkg = mPackages.get(packageName);
20642 sendPackageChangedBroadcast(pkg.getPackageName(),
20643 true /* dontKillApp */,
20644 new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
20646 Intent.ACTION_OVERLAY_CHANGED);
20650 mModuleInfoProvider.systemReady();
20652 // Installer service might attempt to install some packages that have been staged for
20653 // installation on reboot. Make sure this is the last component to be call since the
20654 // installation might require other components to be ready.
20655 mInstallerService.restoreAndApplyStagedSessionIfNeeded();
20658 public void waitForAppDataPrepared() {
20659 if (mPrepareAppDataFuture == null) {
20662 ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20663 mPrepareAppDataFuture = null;
20667 public boolean isSafeMode() {
20668 // allow instant applications
20673 public boolean hasSystemUidErrors() {
20674 // allow instant applications
20675 return mHasSystemUidErrors;
20678 static String arrayToString(int[] array) {
20679 StringBuilder stringBuilder = new StringBuilder(128);
20680 stringBuilder.append('[');
20681 if (array != null) {
20682 for (int i=0; i<array.length; i++) {
20683 if (i > 0) stringBuilder.append(", ");
20684 stringBuilder.append(array[i]);
20687 stringBuilder.append(']');
20688 return stringBuilder.toString();
20692 public void onShellCommand(FileDescriptor in, FileDescriptor out,
20693 FileDescriptor err, String[] args, ShellCallback callback,
20694 ResultReceiver resultReceiver) {
20695 (new PackageManagerShellCommand(this, mPermissionManagerService)).exec(
20696 this, in, out, err, args, callback, resultReceiver);
20699 @SuppressWarnings("resource")
20701 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20702 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
20704 DumpState dumpState = new DumpState();
20705 boolean fullPreferred = false;
20706 boolean checkin = false;
20708 String packageName = null;
20709 ArraySet<String> permissionNames = null;
20712 while (opti < args.length) {
20713 String opt = args[opti];
20714 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
20719 if ("-a".equals(opt)) {
20720 // Right now we only know how to print all.
20721 } else if ("-h".equals(opt)) {
20722 pw.println("Package manager dump options:");
20723 pw.println(" [-h] [-f] [--checkin] [--all-components] [cmd] ...");
20724 pw.println(" --checkin: dump for a checkin");
20725 pw.println(" -f: print details of intent filters");
20726 pw.println(" -h: print this help");
20727 pw.println(" --all-components: include all component names in package dump");
20728 pw.println(" cmd may be one of:");
20729 pw.println(" apex: list active APEXes and APEX session state");
20730 pw.println(" l[ibraries]: list known shared libraries");
20731 pw.println(" f[eatures]: list device features");
20732 pw.println(" k[eysets]: print known keysets");
20733 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
20734 pw.println(" perm[issions]: dump permissions");
20735 pw.println(" permission [name ...]: dump declaration and use of given permission");
20736 pw.println(" pref[erred]: print preferred package settings");
20737 pw.println(" preferred-xml [--full]: print preferred package settings as xml");
20738 pw.println(" prov[iders]: dump content providers");
20739 pw.println(" p[ackages]: dump installed packages");
20740 pw.println(" q[ueries]: dump app queryability calculations");
20741 pw.println(" s[hared-users]: dump shared user IDs");
20742 pw.println(" m[essages]: print collected runtime messages");
20743 pw.println(" v[erifiers]: print package verifier info");
20744 pw.println(" d[omain-preferred-apps]: print domains preferred apps");
20745 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
20746 pw.println(" version: print database version info");
20747 pw.println(" write: write current settings now");
20748 pw.println(" installs: details about install sessions");
20749 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?");
20750 pw.println(" dexopt: dump dexopt state");
20751 pw.println(" compiler-stats: dump compiler statistics");
20752 pw.println(" service-permissions: dump permissions required by services");
20753 pw.println(" <package.name>: info about given package");
20755 } else if ("--checkin".equals(opt)) {
20757 } else if ("--all-components".equals(opt)) {
20758 dumpState.setOptionEnabled(DumpState.OPTION_DUMP_ALL_COMPONENTS);
20759 } else if ("-f".equals(opt)) {
20760 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20761 } else if ("--proto".equals(opt)) {
20765 pw.println("Unknown argument: " + opt + "; use -h for help");
20769 // Is the caller requesting to dump a particular piece of data?
20770 if (opti < args.length) {
20771 String cmd = args[opti];
20773 // Is this a package name?
20774 if ("android".equals(cmd) || cmd.contains(".")) {
20776 // When dumping a single package, we always dump all of its
20777 // filter information since the amount of data will be reasonable.
20778 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20779 } else if ("check-permission".equals(cmd)) {
20780 if (opti >= args.length) {
20781 pw.println("Error: check-permission missing permission argument");
20784 String perm = args[opti];
20786 if (opti >= args.length) {
20787 pw.println("Error: check-permission missing package argument");
20791 String pkg = args[opti];
20793 int user = UserHandle.getUserId(Binder.getCallingUid());
20794 if (opti < args.length) {
20796 user = Integer.parseInt(args[opti]);
20797 } catch (NumberFormatException e) {
20798 pw.println("Error: check-permission user argument is not a number: "
20804 // Normalize package name to handle renamed packages and static libs
20805 pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
20807 pw.println(checkPermission(perm, pkg, user));
20809 } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
20810 dumpState.setDump(DumpState.DUMP_LIBS);
20811 } else if ("f".equals(cmd) || "features".equals(cmd)) {
20812 dumpState.setDump(DumpState.DUMP_FEATURES);
20813 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
20814 if (opti >= args.length) {
20815 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
20816 | DumpState.DUMP_SERVICE_RESOLVERS
20817 | DumpState.DUMP_RECEIVER_RESOLVERS
20818 | DumpState.DUMP_CONTENT_RESOLVERS);
20820 while (opti < args.length) {
20821 String name = args[opti];
20822 if ("a".equals(name) || "activity".equals(name)) {
20823 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
20824 } else if ("s".equals(name) || "service".equals(name)) {
20825 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
20826 } else if ("r".equals(name) || "receiver".equals(name)) {
20827 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
20828 } else if ("c".equals(name) || "content".equals(name)) {
20829 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
20831 pw.println("Error: unknown resolver table type: " + name);
20837 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
20838 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
20839 } else if ("permission".equals(cmd)) {
20840 if (opti >= args.length) {
20841 pw.println("Error: permission requires permission name");
20844 permissionNames = new ArraySet<>();
20845 while (opti < args.length) {
20846 permissionNames.add(args[opti]);
20849 dumpState.setDump(DumpState.DUMP_PERMISSIONS
20850 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
20851 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
20852 dumpState.setDump(DumpState.DUMP_PREFERRED);
20853 } else if ("preferred-xml".equals(cmd)) {
20854 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
20855 if (opti < args.length && "--full".equals(args[opti])) {
20856 fullPreferred = true;
20859 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
20860 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
20861 } else if ("p".equals(cmd) || "packages".equals(cmd)) {
20862 dumpState.setDump(DumpState.DUMP_PACKAGES);
20863 } else if ("q".equals(cmd) || "queries".equals(cmd)) {
20864 dumpState.setDump(DumpState.DUMP_QUERIES);
20865 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
20866 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
20867 if (opti < args.length && "noperm".equals(args[opti])) {
20868 dumpState.setOptionEnabled(DumpState.OPTION_SKIP_PERMISSIONS);
20870 } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
20871 dumpState.setDump(DumpState.DUMP_PROVIDERS);
20872 } else if ("m".equals(cmd) || "messages".equals(cmd)) {
20873 dumpState.setDump(DumpState.DUMP_MESSAGES);
20874 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
20875 dumpState.setDump(DumpState.DUMP_VERIFIERS);
20876 } else if ("i".equals(cmd) || "ifv".equals(cmd)
20877 || "intent-filter-verifiers".equals(cmd)) {
20878 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
20879 } else if ("version".equals(cmd)) {
20880 dumpState.setDump(DumpState.DUMP_VERSION);
20881 } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
20882 dumpState.setDump(DumpState.DUMP_KEYSETS);
20883 } else if ("installs".equals(cmd)) {
20884 dumpState.setDump(DumpState.DUMP_INSTALLS);
20885 } else if ("frozen".equals(cmd)) {
20886 dumpState.setDump(DumpState.DUMP_FROZEN);
20887 } else if ("volumes".equals(cmd)) {
20888 dumpState.setDump(DumpState.DUMP_VOLUMES);
20889 } else if ("dexopt".equals(cmd)) {
20890 dumpState.setDump(DumpState.DUMP_DEXOPT);
20891 } else if ("compiler-stats".equals(cmd)) {
20892 dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
20893 } else if ("changes".equals(cmd)) {
20894 dumpState.setDump(DumpState.DUMP_CHANGES);
20895 } else if ("service-permissions".equals(cmd)) {
20896 dumpState.setDump(DumpState.DUMP_SERVICE_PERMISSIONS);
20897 } else if ("write".equals(cmd)) {
20898 synchronized (mLock) {
20899 mSettings.writeLPr();
20900 pw.println("Settings written.");
20907 pw.println("vers,1");
20911 synchronized (mLock) {
20912 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
20914 if (dumpState.onTitlePrinted())
20916 pw.println("Database versions:");
20917 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " "));
20921 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
20923 if (dumpState.onTitlePrinted())
20925 pw.println("Verifiers:");
20926 pw.print(" Required: ");
20927 pw.print(mRequiredVerifierPackage);
20928 pw.print(" (uid=");
20929 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20930 UserHandle.USER_SYSTEM));
20932 } else if (mRequiredVerifierPackage != null) {
20933 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
20935 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20936 UserHandle.USER_SYSTEM));
20940 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
20941 packageName == null) {
20942 if (mIntentFilterVerifierComponent != null) {
20943 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
20945 if (dumpState.onTitlePrinted())
20947 pw.println("Intent Filter Verifier:");
20948 pw.print(" Using: ");
20949 pw.print(verifierPackageName);
20950 pw.print(" (uid=");
20951 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20952 UserHandle.USER_SYSTEM));
20954 } else if (verifierPackageName != null) {
20955 pw.print("ifv,"); pw.print(verifierPackageName);
20957 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20958 UserHandle.USER_SYSTEM));
20962 pw.println("No Intent Filter Verifier available!");
20966 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
20967 boolean printedHeader = false;
20968 final Iterator<String> it = mSharedLibraries.keySet().iterator();
20969 while (it.hasNext()) {
20970 String libName = it.next();
20971 LongSparseArray<SharedLibraryInfo> versionedLib
20972 = mSharedLibraries.get(libName);
20973 if (versionedLib == null) {
20976 final int versionCount = versionedLib.size();
20977 for (int i = 0; i < versionCount; i++) {
20978 SharedLibraryInfo libraryInfo = versionedLib.valueAt(i);
20980 if (!printedHeader) {
20981 if (dumpState.onTitlePrinted())
20983 pw.println("Libraries:");
20984 printedHeader = true;
20990 pw.print(libraryInfo.getName());
20991 if (libraryInfo.isStatic()) {
20992 pw.print(" version=" + libraryInfo.getLongVersion());
20997 if (libraryInfo.getPath() != null) {
20998 pw.print(" (jar) ");
20999 pw.print(libraryInfo.getPath());
21001 pw.print(" (apk) ");
21002 pw.print(libraryInfo.getPackageName());
21009 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
21010 if (dumpState.onTitlePrinted())
21013 pw.println("Features:");
21016 synchronized (mAvailableFeatures) {
21017 for (FeatureInfo feat : mAvailableFeatures.values()) {
21020 pw.print(feat.name);
21022 pw.println(feat.version);
21025 pw.print(feat.name);
21026 if (feat.version > 0) {
21027 pw.print(" version=");
21028 pw.print(feat.version);
21036 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
21037 mComponentResolver.dumpActivityResolvers(pw, dumpState, packageName);
21039 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
21040 mComponentResolver.dumpReceiverResolvers(pw, dumpState, packageName);
21042 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
21043 mComponentResolver.dumpServiceResolvers(pw, dumpState, packageName);
21045 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
21046 mComponentResolver.dumpProviderResolvers(pw, dumpState, packageName);
21049 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
21050 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21051 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21052 int user = mSettings.mPreferredActivities.keyAt(i);
21054 dumpState.getTitlePrinted()
21055 ? "\nPreferred Activities User " + user + ":"
21056 : "Preferred Activities User " + user + ":", " ",
21057 packageName, true, false)) {
21058 dumpState.setTitlePrinted(true);
21063 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
21065 FileOutputStream fout = new FileOutputStream(fd);
21066 BufferedOutputStream str = new BufferedOutputStream(fout);
21067 XmlSerializer serializer = new FastXmlSerializer();
21069 serializer.setOutput(str, StandardCharsets.UTF_8.name());
21070 serializer.startDocument(null, true);
21071 serializer.setFeature(
21072 "http://xmlpull.org/v1/doc/features.html#indent-output", true);
21073 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
21074 serializer.endDocument();
21075 serializer.flush();
21076 } catch (IllegalArgumentException e) {
21077 pw.println("Failed writing: " + e);
21078 } catch (IllegalStateException e) {
21079 pw.println("Failed writing: " + e);
21080 } catch (IOException e) {
21081 pw.println("Failed writing: " + e);
21086 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
21087 && packageName == null) {
21089 int count = mSettings.mPackages.size();
21091 pw.println("No applications!");
21094 final String prefix = " ";
21095 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
21096 if (allPackageSettings.size() == 0) {
21097 pw.println("No domain preferred apps!");
21100 pw.println("App verification status:");
21103 for (PackageSetting ps : allPackageSettings) {
21104 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
21105 if (ivi == null || ivi.getPackageName() == null) continue;
21106 pw.println(prefix + "Package: " + ivi.getPackageName());
21107 pw.println(prefix + "Domains: " + ivi.getDomainsString());
21108 pw.println(prefix + "Status: " + ivi.getStatusString());
21113 pw.println(prefix + "No app verification established.");
21116 for (int userId : mUserManager.getUserIds()) {
21117 pw.println("App linkages for user " + userId + ":");
21120 for (PackageSetting ps : allPackageSettings) {
21121 final long status = ps.getDomainVerificationStatusForUser(userId);
21122 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
21123 && !DEBUG_DOMAIN_VERIFICATION) {
21126 pw.println(prefix + "Package: " + ps.name);
21127 pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
21128 String statusStr = IntentFilterVerificationInfo.
21129 getStatusStringFromValue(status);
21130 pw.println(prefix + "Status: " + statusStr);
21135 pw.println(prefix + "No configured app linkages.");
21143 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21144 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21147 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21148 mComponentResolver.dumpContentProviders(pw, dumpState, packageName);
21151 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21152 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21155 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21156 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21159 if (dumpState.isDumping(DumpState.DUMP_QUERIES)) {
21160 final PackageSetting setting = mSettings.getPackageLPr(packageName);
21161 Integer filteringAppId = setting == null ? null : setting.appId;
21162 mAppsFilter.dumpQueries(
21163 pw, this, filteringAppId, dumpState,
21164 mUserManager.getUserIds());
21167 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21168 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21171 if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
21172 if (dumpState.onTitlePrinted()) pw.println();
21173 pw.println("Package Changes:");
21174 pw.print(" Sequence number="); pw.println(mChangedPackagesSequenceNumber);
21175 final int K = mChangedPackages.size();
21176 for (int i = 0; i < K; i++) {
21177 final SparseArray<String> changes = mChangedPackages.valueAt(i);
21178 pw.print(" User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
21179 final int N = changes.size();
21181 pw.print(" "); pw.println("No packages changed");
21183 for (int j = 0; j < N; j++) {
21184 final String pkgName = changes.valueAt(j);
21185 final int sequenceNumber = changes.keyAt(j);
21188 pw.print(sequenceNumber);
21189 pw.print(", package=");
21190 pw.println(pkgName);
21196 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21197 // XXX should handle packageName != null by dumping only install data that
21198 // the given package is involved with.
21199 if (dumpState.onTitlePrinted()) pw.println();
21201 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
21203 ipw.println("Frozen packages:");
21204 ipw.increaseIndent();
21205 if (mFrozenPackages.size() == 0) {
21206 ipw.println("(none)");
21208 for (int i = 0; i < mFrozenPackages.size(); i++) {
21209 ipw.println(mFrozenPackages.valueAt(i));
21212 ipw.decreaseIndent();
21215 if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
21216 if (dumpState.onTitlePrinted()) pw.println();
21218 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
21220 ipw.println("Loaded volumes:");
21221 ipw.increaseIndent();
21222 if (mLoadedVolumes.size() == 0) {
21223 ipw.println("(none)");
21225 for (int i = 0; i < mLoadedVolumes.size(); i++) {
21226 ipw.println(mLoadedVolumes.valueAt(i));
21229 ipw.decreaseIndent();
21232 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
21233 && packageName == null) {
21234 mComponentResolver.dumpServicePermissions(pw, dumpState);
21237 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21238 if (dumpState.onTitlePrinted()) pw.println();
21239 dumpDexoptStateLPr(pw, packageName);
21242 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21243 if (dumpState.onTitlePrinted()) pw.println();
21244 dumpCompilerStatsLPr(pw, packageName);
21247 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21248 if (dumpState.onTitlePrinted()) pw.println();
21249 mSettings.dumpReadMessagesLPr(pw, dumpState);
21252 pw.println("Package warning messages:");
21253 dumpCriticalInfo(pw, null);
21256 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21257 dumpCriticalInfo(pw, "msg,");
21261 // PackageInstaller should be called outside of mPackages lock
21262 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21263 // XXX should handle packageName != null by dumping only install data that
21264 // the given package is involved with.
21265 if (dumpState.onTitlePrinted()) pw.println();
21266 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120));
21269 if (!checkin && dumpState.isDumping(DumpState.DUMP_APEX)) {
21270 mApexManager.dump(pw, packageName);
21274 //TODO: b/111402650
21275 private void disableSkuSpecificApps() {
21276 String apkList[] = mContext.getResources().getStringArray(
21277 R.array.config_disableApksUnlessMatchedSku_apk_list);
21278 String skuArray[] = mContext.getResources().getStringArray(
21279 R.array.config_disableApkUnlessMatchedSku_skus_list);
21280 if (ArrayUtils.isEmpty(apkList)) {
21283 String sku = SystemProperties.get("ro.boot.hardware.sku");
21284 if (!TextUtils.isEmpty(sku) && ArrayUtils.contains(skuArray, sku)) {
21287 for (String packageName : apkList) {
21288 setSystemAppHiddenUntilInstalled(packageName, true);
21289 for (UserInfo user : mUserManager.getUsers(false)) {
21290 setSystemAppInstallState(packageName, false, user.id);
21295 private void dumpProto(FileDescriptor fd) {
21296 final ProtoOutputStream proto = new ProtoOutputStream(fd);
21298 synchronized (mLock) {
21299 final long requiredVerifierPackageToken =
21300 proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21301 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21303 PackageServiceDumpProto.PackageShortProto.UID,
21305 mRequiredVerifierPackage,
21306 MATCH_DEBUG_TRIAGED_MISSING,
21307 UserHandle.USER_SYSTEM));
21308 proto.end(requiredVerifierPackageToken);
21310 if (mIntentFilterVerifierComponent != null) {
21311 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21312 final long verifierPackageToken =
21313 proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21314 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21316 PackageServiceDumpProto.PackageShortProto.UID,
21318 verifierPackageName,
21319 MATCH_DEBUG_TRIAGED_MISSING,
21320 UserHandle.USER_SYSTEM));
21321 proto.end(verifierPackageToken);
21324 dumpSharedLibrariesProto(proto);
21325 dumpFeaturesProto(proto);
21326 mSettings.dumpPackagesProto(proto);
21327 mSettings.dumpSharedUsersProto(proto);
21328 dumpCriticalInfo(proto);
21333 private void dumpFeaturesProto(ProtoOutputStream proto) {
21334 synchronized (mAvailableFeatures) {
21335 final int count = mAvailableFeatures.size();
21336 for (int i = 0; i < count; i++) {
21337 mAvailableFeatures.valueAt(i).dumpDebug(proto, PackageServiceDumpProto.FEATURES);
21342 private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21343 final int count = mSharedLibraries.size();
21344 for (int i = 0; i < count; i++) {
21345 final String libName = mSharedLibraries.keyAt(i);
21346 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(libName);
21347 if (versionedLib == null) {
21350 final int versionCount = versionedLib.size();
21351 for (int j = 0; j < versionCount; j++) {
21352 final SharedLibraryInfo libraryInfo = versionedLib.valueAt(j);
21353 final long sharedLibraryToken =
21354 proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21355 proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libraryInfo.getName());
21356 final boolean isJar = (libraryInfo.getPath() != null);
21357 proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21359 proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH,
21360 libraryInfo.getPath());
21362 proto.write(PackageServiceDumpProto.SharedLibraryProto.APK,
21363 libraryInfo.getPackageName());
21365 proto.end(sharedLibraryToken);
21370 @GuardedBy("mLock")
21371 @SuppressWarnings("resource")
21372 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21373 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
21375 ipw.println("Dexopt state:");
21376 ipw.increaseIndent();
21377 Collection<PackageSetting> pkgSettings;
21378 if (packageName != null) {
21379 PackageSetting targetPkgSetting = mSettings.mPackages.get(packageName);
21380 if (targetPkgSetting != null) {
21381 pkgSettings = Collections.singletonList(targetPkgSetting);
21383 ipw.println("Unable to find package: " + packageName);
21387 pkgSettings = mSettings.mPackages.values();
21390 for (PackageSetting pkgSetting : pkgSettings) {
21391 if (pkgSetting.pkg == null) {
21394 ipw.println("[" + pkgSetting.name + "]");
21395 ipw.increaseIndent();
21396 mPackageDexOptimizer.dumpDexoptState(ipw, pkgSetting.pkg, pkgSetting,
21397 mDexManager.getPackageUseInfoOrDefault(pkgSetting.pkg.getPackageName()));
21398 ipw.decreaseIndent();
21402 @GuardedBy("mLock")
21403 @SuppressWarnings("resource")
21404 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
21405 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
21407 ipw.println("Compiler stats:");
21408 ipw.increaseIndent();
21409 Collection<AndroidPackage> packages;
21410 if (packageName != null) {
21411 AndroidPackage targetPackage = mPackages.get(packageName);
21412 if (targetPackage != null) {
21413 packages = Collections.singletonList(targetPackage);
21415 ipw.println("Unable to find package: " + packageName);
21419 packages = mPackages.values();
21422 for (AndroidPackage pkg : packages) {
21423 ipw.println("[" + pkg.getPackageName() + "]");
21424 ipw.increaseIndent();
21426 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.getPackageName());
21427 if (stats == null) {
21428 ipw.println("(No recorded stats)");
21432 ipw.decreaseIndent();
21436 private String dumpDomainString(String packageName) {
21437 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21439 List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21441 ArraySet<String> result = new ArraySet<>();
21442 if (iviList.size() > 0) {
21443 for (IntentFilterVerificationInfo ivi : iviList) {
21444 result.addAll(ivi.getDomains());
21447 if (filters != null && filters.size() > 0) {
21448 for (IntentFilter filter : filters) {
21449 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21450 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21451 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21452 result.addAll(filter.getHostsList());
21457 StringBuilder sb = new StringBuilder(result.size() * 16);
21458 for (String domain : result) {
21459 if (sb.length() > 0) sb.append(" ");
21462 return sb.toString();
21465 // ------- apps on sdcard specific code -------
21466 static final boolean DEBUG_SD_INSTALL = false;
21468 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21470 private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21472 private boolean mMediaMounted = false;
21474 static String getEncryptKey() {
21476 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21477 SD_ENCRYPTION_KEYSTORE_NAME);
21478 if (sdEncKey == null) {
21479 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21480 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21481 if (sdEncKey == null) {
21482 Slog.e(TAG, "Failed to create encryption keys");
21487 } catch (NoSuchAlgorithmException nsae) {
21488 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21490 } catch (IOException ioe) {
21491 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21496 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21497 ArrayList<AndroidPackage> packages, IIntentReceiver finishedReceiver) {
21498 final int size = packages.size();
21499 final String[] packageNames = new String[size];
21500 final int[] packageUids = new int[size];
21501 for (int i = 0; i < size; i++) {
21502 final AndroidPackage pkg = packages.get(i);
21503 packageNames[i] = pkg.getPackageName();
21504 packageUids[i] = pkg.getUid();
21506 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
21510 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21511 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21512 sendResourcesChangedBroadcast(mediaStatus, replacing,
21513 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
21516 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21517 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21518 int size = pkgList.length;
21520 // Send broadcasts here
21521 Bundle extras = new Bundle();
21522 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
21523 if (uidArr != null) {
21524 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
21527 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
21529 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
21530 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
21531 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null, null);
21535 private void loadPrivatePackages(final VolumeInfo vol) {
21536 mHandler.post(() -> loadPrivatePackagesInner(vol));
21539 private void loadPrivatePackagesInner(VolumeInfo vol) {
21540 final String volumeUuid = vol.fsUuid;
21541 if (TextUtils.isEmpty(volumeUuid)) {
21542 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
21546 final ArrayList<PackageFreezer> freezers = new ArrayList<>();
21547 final ArrayList<AndroidPackage> loaded = new ArrayList<>();
21548 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
21550 final VersionInfo ver;
21551 final List<PackageSetting> packages;
21552 synchronized (mLock) {
21553 ver = mSettings.findOrCreateVersion(volumeUuid);
21554 packages = mSettings.getVolumePackagesLPr(volumeUuid);
21557 for (PackageSetting ps : packages) {
21558 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
21559 synchronized (mInstallLock) {
21560 final AndroidPackage pkg;
21562 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
21565 } catch (PackageManagerException e) {
21566 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
21569 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
21570 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
21571 | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY
21572 | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
21577 // Reconcile app data for all started/unlocked users
21578 final StorageManager sm = mInjector.getStorageManager();
21579 UserManagerInternal umInternal = mInjector.getUserManagerInternal();
21580 for (UserInfo user : mUserManager.getUsers(false /* includeDying */)) {
21582 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21583 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21584 } else if (umInternal.isUserRunning(user.id)) {
21585 flags = StorageManager.FLAG_STORAGE_DE;
21591 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
21592 synchronized (mInstallLock) {
21593 reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
21595 } catch (IllegalStateException e) {
21596 // Device was probably ejected, and we'll process that event momentarily
21597 Slog.w(TAG, "Failed to prepare storage: " + e);
21601 synchronized (mLock) {
21602 final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
21604 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21605 + mSdkVersion + "; regranting permissions for " + volumeUuid);
21607 mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated);
21609 // Yay, everything is now upgraded
21610 ver.forceCurrent();
21612 mSettings.writeLPr();
21615 for (PackageFreezer freezer : freezers) {
21619 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
21620 sendResourcesChangedBroadcast(true, false, loaded, null);
21621 mLoadedVolumes.add(vol.getId());
21624 private void unloadPrivatePackages(final VolumeInfo vol) {
21625 mHandler.post(() -> unloadPrivatePackagesInner(vol));
21628 private void unloadPrivatePackagesInner(VolumeInfo vol) {
21629 final String volumeUuid = vol.fsUuid;
21630 if (TextUtils.isEmpty(volumeUuid)) {
21631 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
21635 final ArrayList<AndroidPackage> unloaded = new ArrayList<>();
21636 synchronized (mInstallLock) {
21637 synchronized (mLock) {
21638 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
21639 for (PackageSetting ps : packages) {
21640 if (ps.pkg == null) continue;
21642 final AndroidPackage pkg = ps.pkg;
21643 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21644 final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
21646 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
21647 "unloadPrivatePackagesInner")) {
21648 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
21652 Slog.w(TAG, "Failed to unload " + ps.codePath);
21656 // Try very hard to release any references to this package
21657 // so we don't risk the system server being killed due to
21659 AttributeCache.instance().removePackage(ps.name);
21662 mSettings.writeLPr();
21666 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
21667 sendResourcesChangedBroadcast(false, false, unloaded, null);
21668 mLoadedVolumes.remove(vol.getId());
21670 // Try very hard to release any references to this path so we don't risk
21671 // the system server being killed due to open FDs
21672 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
21674 for (int i = 0; i < 3; i++) {
21676 System.runFinalization();
21680 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
21681 throws PackageManagerException {
21682 synchronized (mLock) {
21683 // Normalize package name to handle renamed packages
21684 packageName = normalizePackageNameLPr(packageName);
21686 final PackageSetting ps = mSettings.mPackages.get(packageName);
21688 throw new PackageManagerException("Package " + packageName + " is unknown");
21689 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21690 throw new PackageManagerException(
21691 "Package " + packageName + " found on unknown volume " + volumeUuid
21692 + "; expected volume " + ps.volumeUuid);
21693 } else if (!ps.getInstalled(userId)) {
21694 throw new PackageManagerException(
21695 "Package " + packageName + " not installed for user " + userId);
21700 private List<String> collectAbsoluteCodePaths() {
21701 synchronized (mLock) {
21702 List<String> codePaths = new ArrayList<>();
21703 final int packageCount = mSettings.mPackages.size();
21704 for (int i = 0; i < packageCount; i++) {
21705 final PackageSetting ps = mSettings.mPackages.valueAt(i);
21706 codePaths.add(ps.codePath.getAbsolutePath());
21713 * Examine all apps present on given mounted volume, and destroy apps that
21714 * aren't expected, either due to uninstallation or reinstallation on
21717 private void reconcileApps(String volumeUuid) {
21718 List<String> absoluteCodePaths = collectAbsoluteCodePaths();
21719 List<File> filesToDelete = null;
21721 final File[] files = FileUtils.listFilesOrEmpty(
21722 Environment.getDataAppDirectory(volumeUuid));
21723 for (File file : files) {
21724 final boolean isPackage = (isApkFile(file) || file.isDirectory())
21725 && !PackageInstallerService.isStageName(file.getName());
21727 // Ignore entries which are not packages
21731 String absolutePath = file.getAbsolutePath();
21733 boolean pathValid = false;
21734 final int absoluteCodePathCount = absoluteCodePaths.size();
21735 for (int i = 0; i < absoluteCodePathCount; i++) {
21736 String absoluteCodePath = absoluteCodePaths.get(i);
21737 if (absoluteCodePath.startsWith(absolutePath)) {
21744 if (filesToDelete == null) {
21745 filesToDelete = new ArrayList<>();
21747 filesToDelete.add(file);
21751 if (filesToDelete != null) {
21752 final int fileToDeleteCount = filesToDelete.size();
21753 for (int i = 0; i < fileToDeleteCount; i++) {
21754 File fileToDelete = filesToDelete.get(i);
21755 logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
21756 synchronized (mInstallLock) {
21757 removeCodePathLI(fileToDelete);
21764 * Reconcile all app data for the given user.
21766 * Verifies that directories exist and that ownership and labeling is
21767 * correct for all installed apps on all mounted volumes.
21769 void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
21770 final StorageManager storage = mInjector.getStorageManager();
21771 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
21772 final String volumeUuid = vol.getFsUuid();
21773 synchronized (mInstallLock) {
21774 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
21779 @GuardedBy("mInstallLock")
21780 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21781 boolean migrateAppData) {
21782 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
21786 * Reconcile all app data on given mounted volume.
21788 * Destroys app data that isn't expected, either due to uninstallation or
21789 * reinstallation on another volume.
21791 * Verifies that directories exist and that ownership and labeling is
21792 * correct for all installed apps.
21793 * @return list of skipped non-core packages (if {@code onlyCoreApps} is true)
21795 @GuardedBy("mInstallLock")
21796 private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21797 boolean migrateAppData, boolean onlyCoreApps) {
21798 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
21799 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
21800 List<String> result = onlyCoreApps ? new ArrayList<>() : null;
21802 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
21803 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
21805 // First look for stale data that doesn't belong, and check if things
21806 // have changed since we did our last restorecon
21807 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
21808 if (StorageManager.isFileEncryptedNativeOrEmulated()
21809 && !StorageManager.isUserKeyUnlocked(userId)) {
21810 throw new RuntimeException(
21811 "Yikes, someone asked us to reconcile CE storage while " + userId
21812 + " was still locked; this would have caused massive data loss!");
21815 final File[] files = FileUtils.listFilesOrEmpty(ceDir);
21816 for (File file : files) {
21817 final String packageName = file.getName();
21819 assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21820 } catch (PackageManagerException e) {
21821 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21823 mInstaller.destroyAppData(volumeUuid, packageName, userId,
21824 StorageManager.FLAG_STORAGE_CE, 0);
21825 } catch (InstallerException e2) {
21826 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21831 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
21832 final File[] files = FileUtils.listFilesOrEmpty(deDir);
21833 for (File file : files) {
21834 final String packageName = file.getName();
21836 assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21837 } catch (PackageManagerException e) {
21838 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21840 mInstaller.destroyAppData(volumeUuid, packageName, userId,
21841 StorageManager.FLAG_STORAGE_DE, 0);
21842 } catch (InstallerException e2) {
21843 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21849 // Ensure that data directories are ready to roll for all packages
21850 // installed for this volume and user
21851 final List<PackageSetting> packages;
21852 synchronized (mLock) {
21853 packages = mSettings.getVolumePackagesLPr(volumeUuid);
21855 int preparedCount = 0;
21856 for (PackageSetting ps : packages) {
21857 final String packageName = ps.name;
21858 if (ps.pkg == null) {
21859 Slog.w(TAG, "Odd, missing scanned package " + packageName);
21860 // TODO: might be due to legacy ASEC apps; we should circle back
21861 // and reconcile again once they're scanned
21864 // Skip non-core apps if requested
21865 if (onlyCoreApps && !ps.pkg.isCoreApp()) {
21866 result.add(packageName);
21870 if (ps.getInstalled(userId)) {
21871 prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
21876 Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
21881 * Prepare app data for the given app just after it was installed or
21882 * upgraded. This method carefully only touches users that it's installed
21883 * for, and it forces a restorecon to handle any seinfo changes.
21885 * Verifies that directories exist and that ownership and labeling is
21886 * correct for all installed apps. If there is an ownership mismatch, it
21887 * will try recovering system apps by wiping data; third-party app data is
21890 * <em>Note: To avoid a deadlock, do not call this method with {@code mLock} lock held</em>
21892 private void prepareAppDataAfterInstallLIF(AndroidPackage pkg) {
21893 final PackageSetting ps;
21894 synchronized (mLock) {
21895 ps = mSettings.mPackages.get(pkg.getPackageName());
21896 mSettings.writeKernelMappingLPr(ps);
21899 UserManagerInternal umInternal = mInjector.getUserManagerInternal();
21900 StorageManagerInternal smInternal = mInjector.getStorageManagerInternal();
21901 for (UserInfo user : mUserManager.getUsers(false /*excludeDying*/)) {
21903 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21904 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21905 } else if (umInternal.isUserRunning(user.id)) {
21906 flags = StorageManager.FLAG_STORAGE_DE;
21911 if (ps.getInstalled(user.id)) {
21912 // TODO: when user data is locked, mark that we're still dirty
21913 prepareAppDataLIF(pkg, user.id, flags);
21915 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21916 // Prepare app data on external storage; currently this is used to
21917 // setup any OBB dirs that were created by the installer correctly.
21918 int uid = UserHandle.getUid(user.id, UserHandle.getAppId(pkg.getUid()));
21919 smInternal.prepareAppDataAfterInstall(pkg.getPackageName(), uid);
21926 * Prepare app data for the given app.
21928 * Verifies that directories exist and that ownership and labeling is
21929 * correct for all installed apps. If there is an ownership mismatch, this
21930 * will try recovering system apps by wiping data; third-party app data is
21933 private void prepareAppDataLIF(AndroidPackage pkg, int userId, int flags) {
21935 Slog.wtf(TAG, "Package was null!", new Throwable());
21938 prepareAppDataLeafLIF(pkg, userId, flags);
21941 private void prepareAppDataAndMigrateLIF(AndroidPackage pkg, int userId, int flags,
21942 boolean maybeMigrateAppData) {
21943 prepareAppDataLIF(pkg, userId, flags);
21945 if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
21946 // We may have just shuffled around app data directories, so
21947 // prepare them one more time
21948 prepareAppDataLIF(pkg, userId, flags);
21952 private void prepareAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
21953 if (DEBUG_APP_DATA) {
21954 Slog.v(TAG, "prepareAppData for " + pkg.getPackageName() + " u" + userId + " 0x"
21955 + Integer.toHexString(flags));
21958 final PackageSetting ps;
21959 synchronized (mLock) {
21960 ps = mSettings.mPackages.get(pkg.getPackageName());
21962 final String volumeUuid = pkg.getVolumeUuid();
21963 final String packageName = pkg.getPackageName();
21965 final int appId = UserHandle.getAppId(pkg.getUid());
21967 String pkgSeInfo = AndroidPackageUtils.getSeInfo(pkg, ps);
21969 Preconditions.checkNotNull(pkgSeInfo);
21971 final String seInfo = pkgSeInfo + (pkg.getSeInfoUser() != null ? pkg.getSeInfoUser() : "");
21972 long ceDataInode = -1;
21974 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21975 appId, seInfo, pkg.getTargetSdkVersion());
21976 } catch (InstallerException e) {
21977 if (pkg.isSystem()) {
21978 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
21979 + ", but trying to recover: " + e);
21980 destroyAppDataLeafLIF(pkg, userId, flags);
21982 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21983 appId, seInfo, pkg.getTargetSdkVersion());
21984 logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
21985 } catch (InstallerException e2) {
21986 logCriticalInfo(Log.DEBUG, "Recovery failed!");
21989 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
21992 // Prepare the application profiles only for upgrades and first boot (so that we don't
21993 // repeat the same operation at each boot).
21994 // We only have to cover the upgrade and first boot here because for app installs we
21995 // prepare the profiles before invoking dexopt (in installPackageLI).
21997 // We also have to cover non system users because we do not call the usual install package
21998 // methods for them.
22000 // NOTE: in order to speed up first boot time we only create the current profile and do not
22001 // update the content of the reference profile. A system image should already be configured
22002 // with the right profile keys and the profiles for the speed-profile prebuilds should
22003 // already be copied. That's done in #performDexOptUpgrade.
22005 // TODO(calin, mathieuc): We should use .dm files for prebuilds profiles instead of
22006 // manually copying them in #performDexOptUpgrade. When we do that we should have a more
22007 // granular check here and only update the existing profiles.
22008 if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) {
22009 mArtManagerService.prepareAppProfiles(pkg, userId,
22010 /* updateReferenceProfileContent= */ false);
22013 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
22014 // TODO: mark this structure as dirty so we persist it!
22015 synchronized (mLock) {
22017 ps.setCeDataInode(ceDataInode, userId);
22022 prepareAppDataContentsLeafLIF(pkg, ps, userId, flags);
22025 private void prepareAppDataContentsLIF(AndroidPackage pkg, @Nullable PackageSetting pkgSetting,
22026 int userId, int flags) {
22028 Slog.wtf(TAG, "Package was null!", new Throwable());
22031 prepareAppDataContentsLeafLIF(pkg, pkgSetting, userId, flags);
22034 private void prepareAppDataContentsLeafLIF(AndroidPackage pkg,
22035 @Nullable PackageSetting pkgSetting, int userId, int flags) {
22036 final String volumeUuid = pkg.getVolumeUuid();
22037 final String packageName = pkg.getPackageName();
22039 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22040 // Create a native library symlink only if we have native libraries
22041 // and if the native libraries are 32 bit libraries. We do not provide
22042 // this symlink for 64 bit libraries.
22043 String primaryCpuAbi = AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting);
22044 if (primaryCpuAbi != null && !VMRuntime.is64BitAbi(primaryCpuAbi)) {
22045 final String nativeLibPath = pkg.getNativeLibraryDir();
22047 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
22048 nativeLibPath, userId);
22049 } catch (InstallerException e) {
22050 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
22057 * For system apps on non-FBE devices, this method migrates any existing
22058 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
22059 * requested by the app.
22061 private boolean maybeMigrateAppDataLIF(AndroidPackage pkg, int userId) {
22062 if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
22063 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
22064 final int storageTarget = pkg.isDefaultToDeviceProtectedStorage()
22065 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
22067 mInstaller.migrateAppData(pkg.getVolumeUuid(), pkg.getPackageName(), userId,
22069 } catch (InstallerException e) {
22070 logCriticalInfo(Log.WARN,
22071 "Failed to migrate " + pkg.getPackageName() + ": " + e.getMessage());
22079 public PackageFreezer freezePackage(String packageName, String killReason) {
22080 return freezePackage(packageName, UserHandle.USER_ALL, killReason);
22083 public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
22084 return new PackageFreezer(packageName, userId, killReason);
22087 public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
22088 String killReason) {
22089 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
22092 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
22093 String killReason) {
22094 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
22095 return new PackageFreezer();
22097 return freezePackage(packageName, userId, killReason);
22101 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
22102 String killReason) {
22103 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
22106 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
22107 String killReason) {
22108 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
22109 return new PackageFreezer();
22111 return freezePackage(packageName, userId, killReason);
22116 * Class that freezes and kills the given package upon creation, and
22117 * unfreezes it upon closing. This is typically used when doing surgery on
22118 * app code/data to prevent the app from running while you're working.
22120 private class PackageFreezer implements AutoCloseable {
22121 private final String mPackageName;
22123 private final boolean mWeFroze;
22125 private final AtomicBoolean mClosed = new AtomicBoolean();
22126 private final CloseGuard mCloseGuard = CloseGuard.get();
22129 * Create and return a stub freezer that doesn't actually do anything,
22130 * typically used when someone requested
22131 * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22132 * {@link PackageManager#DELETE_DONT_KILL_APP}.
22134 public PackageFreezer() {
22135 mPackageName = null;
22137 mCloseGuard.open("close");
22140 public PackageFreezer(String packageName, int userId, String killReason) {
22141 synchronized (mLock) {
22142 mPackageName = packageName;
22143 mWeFroze = mFrozenPackages.add(mPackageName);
22145 final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22147 killApplication(ps.name, ps.appId, userId, killReason);
22150 mCloseGuard.open("close");
22154 protected void finalize() throws Throwable {
22156 mCloseGuard.warnIfOpen();
22164 public void close() {
22165 mCloseGuard.close();
22166 if (mClosed.compareAndSet(false, true)) {
22167 synchronized (mLock) {
22169 mFrozenPackages.remove(mPackageName);
22177 * Verify that given package is currently frozen.
22179 private void checkPackageFrozen(String packageName) {
22180 synchronized (mLock) {
22181 if (!mFrozenPackages.contains(packageName)) {
22182 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
22188 public int movePackage(final String packageName, final String volumeUuid) {
22189 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22191 final int callingUid = Binder.getCallingUid();
22192 final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
22193 final int moveId = mNextMoveId.getAndIncrement();
22194 mHandler.post(() -> {
22196 movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
22197 } catch (PackageManagerException e) {
22198 Slog.w(TAG, "Failed to move " + packageName, e);
22199 mMoveCallbacks.notifyStatusChanged(moveId, e.error);
22205 private void movePackageInternal(final String packageName, final String volumeUuid,
22206 final int moveId, final int callingUid, UserHandle user)
22207 throws PackageManagerException {
22208 final StorageManager storage = mInjector.getStorageManager();
22209 final PackageManager pm = mContext.getPackageManager();
22211 final String currentVolumeUuid;
22212 final File codeFile;
22213 final InstallSource installSource;
22214 final String packageAbiOverride;
22216 final String seinfo;
22217 final String label;
22218 final int targetSdkVersion;
22219 final PackageFreezer freezer;
22220 final int[] installedUserIds;
22221 final boolean isCurrentLocationExternal;
22222 final String fromCodePath;
22225 synchronized (mLock) {
22226 final AndroidPackage pkg = mPackages.get(packageName);
22227 final PackageSetting ps = mSettings.mPackages.get(packageName);
22230 || shouldFilterApplicationLocked(ps, callingUid, user.getIdentifier())) {
22231 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
22233 if (pkg.isSystem()) {
22234 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22235 "Cannot move system application");
22238 final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22239 final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22240 com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22241 if (isInternalStorage && !allow3rdPartyOnInternal) {
22242 throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22243 "3rd party apps are not allowed on internal storage");
22246 currentVolumeUuid = ps.volumeUuid;
22248 final File probe = new File(pkg.getCodePath());
22249 final File probeOat = new File(probe, "oat");
22250 if (!probe.isDirectory() || !probeOat.isDirectory()) {
22251 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22252 "Move only supported for modern cluster style installs");
22255 if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22256 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22257 "Package already moved to " + volumeUuid);
22259 if (!pkg.isExternalStorage() && isPackageDeviceAdminOnAnyUser(packageName)) {
22260 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
22261 "Device admin cannot be moved");
22264 if (mFrozenPackages.contains(packageName)) {
22265 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
22266 "Failed to move already frozen package");
22269 isCurrentLocationExternal = pkg.isExternalStorage();
22270 codeFile = new File(pkg.getCodePath());
22271 installSource = ps.installSource;
22272 packageAbiOverride = ps.cpuAbiOverrideString;
22273 appId = UserHandle.getAppId(pkg.getUid());
22274 seinfo = AndroidPackageUtils.getSeInfo(pkg, ps);
22275 label = String.valueOf(pm.getApplicationLabel(pkg.toAppInfoWithoutState()));
22276 targetSdkVersion = pkg.getTargetSdkVersion();
22277 freezer = freezePackage(packageName, "movePackageInternal");
22278 installedUserIds = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
22279 if (codeFile.getParentFile().getName().startsWith(RANDOM_DIR_PREFIX)) {
22280 fromCodePath = codeFile.getParentFile().getAbsolutePath();
22282 fromCodePath = codeFile.getAbsolutePath();
22286 final Bundle extras = new Bundle();
22287 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
22288 extras.putString(Intent.EXTRA_TITLE, label);
22289 mMoveCallbacks.notifyCreated(moveId, extras);
22292 final boolean moveCompleteApp;
22293 final File measurePath;
22295 installFlags = INSTALL_INTERNAL;
22296 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
22297 moveCompleteApp = true;
22298 measurePath = Environment.getDataAppDirectory(volumeUuid);
22299 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
22300 moveCompleteApp = false;
22301 measurePath = storage.getPrimaryPhysicalVolume().getPath();
22303 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
22304 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
22305 || !volume.isMountedWritable()) {
22307 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22308 "Move location not mounted private volume");
22311 moveCompleteApp = true;
22312 measurePath = Environment.getDataAppDirectory(volumeUuid);
22315 // If we're moving app data around, we need all the users unlocked
22316 if (moveCompleteApp) {
22317 for (int userId : installedUserIds) {
22318 if (StorageManager.isFileEncryptedNativeOrEmulated()
22319 && !StorageManager.isUserKeyUnlocked(userId)) {
22320 throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
22321 "User " + userId + " must be unlocked");
22326 final PackageStats stats = new PackageStats(null, -1);
22327 synchronized (mInstaller) {
22328 for (int userId : installedUserIds) {
22329 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22331 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22332 "Failed to measure package size");
22337 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
22340 final long startFreeBytes = measurePath.getUsableSpace();
22341 final long sizeBytes;
22342 if (moveCompleteApp) {
22343 sizeBytes = stats.codeSize + stats.dataSize;
22345 sizeBytes = stats.codeSize;
22348 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
22350 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22351 "Not enough free space to move");
22354 mMoveCallbacks.notifyStatusChanged(moveId, 10);
22356 final CountDownLatch installedLatch = new CountDownLatch(1);
22357 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
22359 public void onUserActionRequired(Intent intent) throws RemoteException {
22360 throw new IllegalStateException();
22364 public void onPackageInstalled(String basePackageName, int returnCode, String msg,
22365 Bundle extras) throws RemoteException {
22366 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
22367 + PackageManager.installStatusToString(returnCode, msg));
22369 installedLatch.countDown();
22372 final int status = PackageManager.installStatusToPublicStatus(returnCode);
22374 case PackageInstaller.STATUS_SUCCESS:
22375 mMoveCallbacks.notifyStatusChanged(moveId,
22376 PackageManager.MOVE_SUCCEEDED);
22377 logAppMovedStorage(packageName, isCurrentLocationExternal);
22379 case PackageInstaller.STATUS_FAILURE_STORAGE:
22380 mMoveCallbacks.notifyStatusChanged(moveId,
22381 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
22384 mMoveCallbacks.notifyStatusChanged(moveId,
22385 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22391 final MoveInfo move;
22392 if (moveCompleteApp) {
22393 // Kick off a thread to report progress estimates
22397 if (installedLatch.await(1, TimeUnit.SECONDS)) {
22400 } catch (InterruptedException ignored) {
22403 final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
22404 final int progress = 10 + (int) MathUtils.constrain(
22405 ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
22406 mMoveCallbacks.notifyStatusChanged(moveId, progress);
22410 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
22411 appId, seinfo, targetSdkVersion, fromCodePath);
22416 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
22418 final Message msg = mHandler.obtainMessage(INIT_COPY);
22419 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
22420 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
22421 installSource, volumeUuid, null /*verificationInfo*/, user,
22422 packageAbiOverride, null /*grantedPermissions*/,
22423 null /*whitelistedRestrictedPermissions*/, PackageParser.SigningDetails.UNKNOWN,
22424 PackageManager.INSTALL_REASON_UNKNOWN, PackageManager.VERSION_CODE_HIGHEST,
22425 DataLoaderType.NONE);
22426 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
22429 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
22430 System.identityHashCode(msg.obj));
22431 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
22432 System.identityHashCode(msg.obj));
22434 mHandler.sendMessage(msg);
22438 * Logs that an app has been moved from internal to external storage and vice versa.
22439 * @param packageName The package that was moved.
22441 private void logAppMovedStorage(String packageName, boolean isPreviousLocationExternal) {
22442 final AndroidPackage pkg;
22443 synchronized (mLock) {
22444 pkg = mPackages.get(packageName);
22450 final StorageManager storage = mInjector.getStorageManager();;
22451 VolumeInfo volume = storage.findVolumeByUuid(pkg.getStorageUuid().toString());
22452 int packageExternalStorageType = getPackageExternalStorageType(volume, pkg.isExternalStorage());
22454 if (!isPreviousLocationExternal && pkg.isExternalStorage()) {
22455 // Move from internal to external storage.
22456 FrameworkStatsLog.write(FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED,
22457 packageExternalStorageType,
22458 FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_EXTERNAL,
22460 } else if (isPreviousLocationExternal && !pkg.isExternalStorage()) {
22461 // Move from external to internal storage.
22462 FrameworkStatsLog.write(FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED,
22463 packageExternalStorageType,
22464 FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_INTERNAL,
22470 public int movePrimaryStorage(String volumeUuid) throws RemoteException {
22471 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22473 final int realMoveId = mNextMoveId.getAndIncrement();
22474 final Bundle extras = new Bundle();
22475 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
22476 mMoveCallbacks.notifyCreated(realMoveId, extras);
22478 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
22480 public void onCreated(int moveId, Bundle extras) {
22485 public void onStatusChanged(int moveId, int status, long estMillis) {
22486 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
22490 final StorageManager storage = mInjector.getStorageManager();
22491 storage.setPrimaryStorageUuid(volumeUuid, callback);
22496 public int getMoveStatus(int moveId) {
22497 mContext.enforceCallingOrSelfPermission(
22498 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22499 return mMoveCallbacks.mLastStatus.get(moveId);
22503 public void registerMoveCallback(IPackageMoveObserver callback) {
22504 mContext.enforceCallingOrSelfPermission(
22505 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22506 mMoveCallbacks.register(callback);
22510 public void unregisterMoveCallback(IPackageMoveObserver callback) {
22511 mContext.enforceCallingOrSelfPermission(
22512 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22513 mMoveCallbacks.unregister(callback);
22517 public boolean setInstallLocation(int loc) {
22518 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
22520 if (getInstallLocation() == loc) {
22523 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
22524 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
22525 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
22526 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
22533 public int getInstallLocation() {
22534 // allow instant app access
22535 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
22536 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
22537 PackageHelper.APP_INSTALL_AUTO);
22540 /** Called by UserManagerService */
22541 void cleanUpUser(UserManagerService userManager, @UserIdInt int userId) {
22542 synchronized (mLock) {
22543 mDirtyUsers.remove(userId);
22544 mUserNeedsBadging.delete(userId);
22545 mSettings.removeUserLPw(userId);
22546 mPendingBroadcasts.remove(userId);
22547 mInstantAppRegistry.onUserRemovedLPw(userId);
22548 removeUnusedPackagesLPw(userManager, userId);
22553 * We're removing userId and would like to remove any downloaded packages
22554 * that are no longer in use by any other user.
22555 * @param userId the user being removed
22557 @GuardedBy("mLock")
22558 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userId) {
22559 final boolean DEBUG_CLEAN_APKS = false;
22560 int [] users = userManager.getUserIds();
22561 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
22562 while (psit.hasNext()) {
22563 PackageSetting ps = psit.next();
22564 if (ps.pkg == null) {
22567 final String packageName = ps.pkg.getPackageName();
22568 // Skip over if system app or static shared library
22569 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0
22570 || !TextUtils.isEmpty(ps.pkg.getStaticSharedLibName())) {
22573 if (DEBUG_CLEAN_APKS) {
22574 Slog.i(TAG, "Checking package " + packageName);
22576 boolean keep = shouldKeepUninstalledPackageLPr(packageName);
22578 if (DEBUG_CLEAN_APKS) {
22579 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO");
22582 for (int i = 0; i < users.length; i++) {
22583 if (users[i] != userId && ps.getInstalled(users[i])) {
22585 if (DEBUG_CLEAN_APKS) {
22586 Slog.i(TAG, " Keeping package " + packageName + " for user "
22594 if (DEBUG_CLEAN_APKS) {
22595 Slog.i(TAG, " Removing package " + packageName);
22598 mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22605 * Called by UserManagerService.
22607 * @param installablePackages system packages that should be initially installed for this user,
22608 * or {@code null} if all system packages should be installed
22609 * @param disallowedPackages packages that should not be initially installed. Takes precedence
22610 * over installablePackages.
22612 void createNewUser(int userId, @Nullable Set<String> installablePackages,
22613 String[] disallowedPackages) {
22614 synchronized (mInstallLock) {
22615 mSettings.createNewUserLI(this, mInstaller, userId,
22616 installablePackages, disallowedPackages);
22618 synchronized (mLock) {
22619 scheduleWritePackageRestrictionsLocked(userId);
22620 scheduleWritePackageListLocked(userId);
22621 primeDomainVerificationsLPw(userId);
22625 void onNewUserCreated(final int userId) {
22626 mPermissionManager.onNewUserCreated(userId);
22629 boolean readPermissionStateForUser(@UserIdInt int userId) {
22630 synchronized (mPackages) {
22631 mSettings.readPermissionStateForUserSyncLPr(userId);
22632 return mSettings.areDefaultRuntimePermissionsGrantedLPr(userId);
22637 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
22638 mContext.enforceCallingOrSelfPermission(
22639 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
22640 "Only package verification agents can read the verifier device identity");
22642 synchronized (mLock) {
22643 return mSettings.getVerifierDeviceIdentityLPw();
22648 public boolean isStorageLow() {
22649 // allow instant applications
22650 final long token = Binder.clearCallingIdentity();
22652 final DeviceStorageMonitorInternal
22653 dsm = mInjector.getDeviceStorageMonitorInternal();
22655 return dsm.isMemoryLow();
22660 Binder.restoreCallingIdentity(token);
22665 public IPackageInstaller getPackageInstaller() {
22666 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
22669 return mInstallerService;
22673 public IArtManager getArtManager() {
22674 return mArtManagerService;
22677 private boolean userNeedsBadging(int userId) {
22678 int index = mUserNeedsBadging.indexOfKey(userId);
22680 final UserInfo userInfo;
22681 final long token = Binder.clearCallingIdentity();
22683 userInfo = mUserManager.getUserInfo(userId);
22685 Binder.restoreCallingIdentity(token);
22688 if (userInfo != null && userInfo.isManagedProfile()) {
22693 mUserNeedsBadging.put(userId, b);
22696 return mUserNeedsBadging.valueAt(index);
22700 public KeySet getKeySetByAlias(String packageName, String alias) {
22701 if (packageName == null || alias == null) {
22704 synchronized(mLock) {
22705 final AndroidPackage pkg = mPackages.get(packageName);
22707 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22708 throw new IllegalArgumentException("Unknown package: " + packageName);
22710 final PackageSetting ps = getPackageSetting(pkg.getPackageName());
22711 if (shouldFilterApplicationLocked(
22712 ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
22713 Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
22714 throw new IllegalArgumentException("Unknown package: " + packageName);
22716 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22717 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
22722 public KeySet getSigningKeySet(String packageName) {
22723 if (packageName == null) {
22726 synchronized (mLock) {
22727 final int callingUid = Binder.getCallingUid();
22728 final int callingUserId = UserHandle.getUserId(callingUid);
22729 final AndroidPackage pkg = mPackages.get(packageName);
22731 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22732 throw new IllegalArgumentException("Unknown package: " + packageName);
22734 final PackageSetting ps = getPackageSetting(pkg.getPackageName());
22735 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
22736 // filter and pretend the package doesn't exist
22737 Slog.w(TAG, "KeySet requested for filtered package: " + packageName
22738 + ", uid:" + callingUid);
22739 throw new IllegalArgumentException("Unknown package: " + packageName);
22741 if (pkg.getUid() != callingUid
22742 && Process.SYSTEM_UID != callingUid) {
22743 throw new SecurityException("May not access signing KeySet of other apps.");
22745 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22746 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
22751 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
22752 final int callingUid = Binder.getCallingUid();
22753 if (getInstantAppPackageName(callingUid) != null) {
22756 if (packageName == null || ks == null) {
22759 synchronized(mLock) {
22760 final AndroidPackage pkg = mPackages.get(packageName);
22762 || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
22763 callingUid, UserHandle.getUserId(callingUid))) {
22764 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22765 throw new IllegalArgumentException("Unknown package: " + packageName);
22767 IBinder ksh = ks.getToken();
22768 if (ksh instanceof KeySetHandle) {
22769 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22770 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
22777 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
22778 final int callingUid = Binder.getCallingUid();
22779 if (getInstantAppPackageName(callingUid) != null) {
22782 if (packageName == null || ks == null) {
22785 synchronized (mLock) {
22786 final AndroidPackage pkg = mPackages.get(packageName);
22788 || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
22789 callingUid, UserHandle.getUserId(callingUid))) {
22790 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22791 throw new IllegalArgumentException("Unknown package: " + packageName);
22793 IBinder ksh = ks.getToken();
22794 if (ksh instanceof KeySetHandle) {
22795 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22796 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
22802 @GuardedBy("mLock")
22803 private void deletePackageIfUnusedLPr(final String packageName) {
22804 PackageSetting ps = mSettings.mPackages.get(packageName);
22808 if (!ps.isAnyInstalled(mUserManager.getUserIds())) {
22809 // TODO Implement atomic delete if package is unused
22810 // It is currently possible that the package will be deleted even if it is installed
22811 // after this method returns.
22812 mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22813 0, PackageManager.DELETE_ALL_USERS));
22818 * Check and throw if the given before/after packages would be considered a
22821 private static void checkDowngrade(AndroidPackage before, PackageInfoLite after)
22822 throws PackageManagerException {
22823 if (after.getLongVersionCode() < before.getLongVersionCode()) {
22824 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22825 "Update version code " + after.versionCode + " is older than current "
22826 + before.getLongVersionCode());
22827 } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
22828 if (after.baseRevisionCode < before.getBaseRevisionCode()) {
22829 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22830 "Update base revision code " + after.baseRevisionCode
22831 + " is older than current " + before.getBaseRevisionCode());
22834 if (!ArrayUtils.isEmpty(after.splitNames)) {
22835 for (int i = 0; i < after.splitNames.length; i++) {
22836 final String splitName = after.splitNames[i];
22837 final int j = ArrayUtils.indexOf(before.getSplitNames(), splitName);
22839 if (after.splitRevisionCodes[i] < before.getSplitRevisionCodes()[j]) {
22840 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22841 "Update split " + splitName + " revision code "
22842 + after.splitRevisionCodes[i] + " is older than current "
22843 + before.getSplitRevisionCodes()[j]);
22851 private static class MoveCallbacks extends Handler {
22852 private static final int MSG_CREATED = 1;
22853 private static final int MSG_STATUS_CHANGED = 2;
22855 private final RemoteCallbackList<IPackageMoveObserver>
22856 mCallbacks = new RemoteCallbackList<>();
22858 private final SparseIntArray mLastStatus = new SparseIntArray();
22860 public MoveCallbacks(Looper looper) {
22864 public void register(IPackageMoveObserver callback) {
22865 mCallbacks.register(callback);
22868 public void unregister(IPackageMoveObserver callback) {
22869 mCallbacks.unregister(callback);
22873 public void handleMessage(Message msg) {
22874 final SomeArgs args = (SomeArgs) msg.obj;
22875 final int n = mCallbacks.beginBroadcast();
22876 for (int i = 0; i < n; i++) {
22877 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
22879 invokeCallback(callback, msg.what, args);
22880 } catch (RemoteException ignored) {
22883 mCallbacks.finishBroadcast();
22887 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
22888 throws RemoteException {
22890 case MSG_CREATED: {
22891 callback.onCreated(args.argi1, (Bundle) args.arg2);
22894 case MSG_STATUS_CHANGED: {
22895 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
22901 private void notifyCreated(int moveId, Bundle extras) {
22902 Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
22904 final SomeArgs args = SomeArgs.obtain();
22905 args.argi1 = moveId;
22906 args.arg2 = extras;
22907 obtainMessage(MSG_CREATED, args).sendToTarget();
22910 private void notifyStatusChanged(int moveId, int status) {
22911 notifyStatusChanged(moveId, status, -1);
22914 private void notifyStatusChanged(int moveId, int status, long estMillis) {
22915 Slog.v(TAG, "Move " + moveId + " status " + status);
22917 final SomeArgs args = SomeArgs.obtain();
22918 args.argi1 = moveId;
22919 args.argi2 = status;
22920 args.arg3 = estMillis;
22921 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
22923 synchronized (mLastStatus) {
22924 mLastStatus.put(moveId, status);
22929 private class PackageManagerNative extends IPackageManagerNative.Stub {
22931 public String[] getAllPackages() {
22932 return PackageManagerService.this.getAllPackages().toArray(new String[0]);
22936 public String[] getNamesForUids(int[] uids) throws RemoteException {
22937 final String[] results = PackageManagerService.this.getNamesForUids(uids);
22938 // massage results so they can be parsed by the native binder
22939 for (int i = results.length - 1; i >= 0; --i) {
22940 if (results[i] == null) {
22947 // NB: this differentiates between preloads and sideloads
22949 public String getInstallerForPackage(String packageName) throws RemoteException {
22950 final String installerName = getInstallerPackageName(packageName);
22951 if (!TextUtils.isEmpty(installerName)) {
22952 return installerName;
22954 // differentiate between preload and sideload
22955 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22956 ApplicationInfo appInfo = getApplicationInfo(packageName,
22958 /*userId*/ callingUser);
22959 if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22966 public long getVersionCodeForPackage(String packageName) throws RemoteException {
22968 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22969 PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
22970 if (pInfo != null) {
22971 return pInfo.getLongVersionCode();
22973 } catch (Exception e) {
22979 public int getTargetSdkVersionForPackage(String packageName)
22980 throws RemoteException {
22981 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22982 ApplicationInfo info = getApplicationInfo(packageName, 0, callingUser);
22983 if (info == null) {
22984 throw new RemoteException(
22985 "Couldn't get ApplicationInfo for package " + packageName);
22987 return info.targetSdkVersion;
22991 public boolean[] isAudioPlaybackCaptureAllowed(String[] packageNames)
22992 throws RemoteException {
22993 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22994 boolean[] results = new boolean[packageNames.length];
22995 for (int i = results.length - 1; i >= 0; --i) {
22996 ApplicationInfo appInfo = getApplicationInfo(packageNames[i], 0, callingUser);
22997 results[i] = appInfo == null ? false : appInfo.isAudioPlaybackCaptureAllowed();
23003 public int getLocationFlags(String packageName) throws RemoteException {
23004 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
23005 ApplicationInfo appInfo = getApplicationInfo(packageName,
23007 /*userId*/ callingUser);
23008 if (appInfo == null) {
23009 throw new RemoteException(
23010 "Couldn't get ApplicationInfo for package " + packageName);
23012 return ((appInfo.isSystemApp() ? IPackageManagerNative.LOCATION_SYSTEM : 0)
23013 | (appInfo.isVendor() ? IPackageManagerNative.LOCATION_VENDOR : 0)
23014 | (appInfo.isProduct() ? IPackageManagerNative.LOCATION_PRODUCT : 0));
23018 public String getModuleMetadataPackageName() throws RemoteException {
23019 return PackageManagerService.this.mModuleInfoProvider.getPackageName();
23023 private class PackageManagerInternalImpl extends PackageManagerInternal {
23025 public List<ApplicationInfo> getInstalledApplications(int flags, int userId,
23027 return PackageManagerService.this.getInstalledApplicationsListInternal(flags, userId,
23033 public boolean isPlatformSigned(String packageName) {
23034 PackageSetting packageSetting = mSettings.mPackages.get(packageName);
23035 if (packageSetting == null) {
23038 AndroidPackage pkg = packageSetting.pkg;
23040 // May happen if package in on a removable sd card
23043 return pkg.getSigningDetails().hasAncestorOrSelf(mPlatformPackage.getSigningDetails())
23044 || mPlatformPackage.getSigningDetails().checkCapability(pkg.getSigningDetails(),
23045 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
23049 public boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName) {
23050 SigningDetails sd = getSigningDetails(packageName);
23054 return sd.hasSha256Certificate(restoringFromSigHash,
23055 SigningDetails.CertCapabilities.INSTALLED_DATA);
23059 public boolean isDataRestoreSafe(Signature restoringFromSig, String packageName) {
23060 SigningDetails sd = getSigningDetails(packageName);
23064 return sd.hasCertificate(restoringFromSig,
23065 SigningDetails.CertCapabilities.INSTALLED_DATA);
23069 public boolean hasSignatureCapability(int serverUid, int clientUid,
23070 @SigningDetails.CertCapabilities int capability) {
23071 SigningDetails serverSigningDetails = getSigningDetails(serverUid);
23072 SigningDetails clientSigningDetails = getSigningDetails(clientUid);
23073 return serverSigningDetails.checkCapability(clientSigningDetails, capability)
23074 || clientSigningDetails.hasAncestorOrSelf(serverSigningDetails);
23078 private SigningDetails getSigningDetails(@NonNull String packageName) {
23079 synchronized (mLock) {
23080 AndroidPackage p = mPackages.get(packageName);
23084 return p.getSigningDetails();
23088 private SigningDetails getSigningDetails(int uid) {
23089 synchronized (mLock) {
23090 final int appId = UserHandle.getAppId(uid);
23091 final Object obj = mSettings.getSettingLPr(appId);
23093 if (obj instanceof SharedUserSetting) {
23094 return ((SharedUserSetting) obj).signatures.mSigningDetails;
23095 } else if (obj instanceof PackageSetting) {
23096 final PackageSetting ps = (PackageSetting) obj;
23097 return ps.signatures.mSigningDetails;
23100 return SigningDetails.UNKNOWN;
23105 public boolean isInstantApp(String packageName, int userId) {
23106 return PackageManagerService.this.isInstantApp(packageName, userId);
23110 public String getInstantAppPackageName(int uid) {
23111 return PackageManagerService.this.getInstantAppPackageName(uid);
23115 public boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
23116 synchronized (mLock) {
23117 PackageSetting ps = getPackageSetting(pkg.getPackageName());
23118 return PackageManagerService.this.shouldFilterApplicationLocked(ps, callingUid,
23124 public boolean filterAppAccess(String packageName, int callingUid, int userId) {
23125 synchronized (mLock) {
23126 PackageSetting ps = getPackageSetting(packageName);
23127 return PackageManagerService.this.shouldFilterApplicationLocked(ps, callingUid,
23133 public AndroidPackage getPackage(String packageName) {
23134 synchronized (mLock) {
23135 packageName = resolveInternalPackageNameLPr(
23136 packageName, PackageManager.VERSION_CODE_HIGHEST);
23137 return mPackages.get(packageName);
23142 public AndroidPackage getPackage(int uid) {
23143 synchronized (mLock) {
23144 final String[] packageNames = getPackagesForUidInternal(uid, Process.SYSTEM_UID);
23145 AndroidPackage pkg = null;
23146 final int numPackages = packageNames == null ? 0 : packageNames.length;
23147 for (int i = 0; pkg == null && i < numPackages; i++) {
23148 pkg = mPackages.get(packageNames[i]);
23156 public PackageSetting getPackageSetting(String packageName) {
23157 return PackageManagerService.this.getPackageSetting(packageName);
23161 public PackageList getPackageList(PackageListObserver observer) {
23162 synchronized (mLock) {
23163 final int N = mPackages.size();
23164 final ArrayList<String> list = new ArrayList<>(N);
23165 for (int i = 0; i < N; i++) {
23166 list.add(mPackages.keyAt(i));
23168 final PackageList packageList = new PackageList(list, observer);
23169 if (observer != null) {
23170 mPackageListObservers.add(packageList);
23172 return packageList;
23177 public void removePackageListObserver(PackageListObserver observer) {
23178 synchronized (mLock) {
23179 mPackageListObservers.remove(observer);
23184 public PackageSetting getDisabledSystemPackage(@NonNull String packageName) {
23185 synchronized (mLock) {
23186 return mSettings.getDisabledSystemPkgLPr(packageName);
23192 String getDisabledSystemPackageName(@NonNull String packageName) {
23193 PackageSetting disabledPkgSetting = (PackageSetting) getDisabledSystemPackage(
23195 AndroidPackage disabledPkg = disabledPkgSetting == null ? null : disabledPkgSetting.pkg;
23196 return disabledPkg == null ? null : disabledPkg.getPackageName();
23200 * Only keep package names that refer to {@link PackageParser.Package#isSystem system}
23203 * @param pkgNames The packages to filter
23205 * @return The filtered packages
23207 private @NonNull String[] filterOnlySystemPackages(@Nullable String... pkgNames) {
23208 if (pkgNames == null) {
23209 return ArrayUtils.emptyArray(String.class);
23212 ArrayList<String> systemPackageNames = new ArrayList<>(pkgNames.length);
23214 for (String pkgName: pkgNames) {
23215 synchronized (mLock) {
23216 if (pkgName == null) {
23220 AndroidPackage pkg = getPackage(pkgName);
23222 Log.w(TAG, "Could not find package " + pkgName);
23226 if (!pkg.isSystem()) {
23227 Log.w(TAG, pkgName + " is not system");
23231 systemPackageNames.add(pkgName);
23235 return systemPackageNames.toArray(new String[]{});
23239 public @NonNull String[] getKnownPackageNames(int knownPackage, int userId) {
23240 return dropNonSystemPackages(getKnownPackageNamesInternal(knownPackage, userId));
23243 private String[] getKnownPackageNamesInternal(int knownPackage, int userId) {
23244 switch (knownPackage) {
23245 case PackageManagerInternal.PACKAGE_BROWSER:
23246 return new String[]{mPermissionManager.getDefaultBrowser(userId)};
23247 case PackageManagerInternal.PACKAGE_INSTALLER:
23248 return filterOnlySystemPackages(mRequiredInstallerPackage);
23249 case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
23250 return filterOnlySystemPackages(mSetupWizardPackage);
23251 case PackageManagerInternal.PACKAGE_SYSTEM:
23252 return new String[]{"android"};
23253 case PackageManagerInternal.PACKAGE_VERIFIER:
23254 return filterOnlySystemPackages(mRequiredVerifierPackage);
23255 case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER:
23256 return filterOnlySystemPackages(
23257 mDefaultTextClassifierPackage, mSystemTextClassifierPackageName);
23258 case PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER:
23259 return filterOnlySystemPackages(mRequiredPermissionControllerPackage);
23260 case PackageManagerInternal.PACKAGE_WELLBEING:
23261 return filterOnlySystemPackages(mWellbeingPackage);
23262 case PackageManagerInternal.PACKAGE_DOCUMENTER:
23263 return filterOnlySystemPackages(mDocumenterPackage);
23264 case PackageManagerInternal.PACKAGE_CONFIGURATOR:
23265 return filterOnlySystemPackages(mConfiguratorPackage);
23266 case PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER:
23267 return filterOnlySystemPackages(mIncidentReportApproverPackage);
23268 case PackageManagerInternal.PACKAGE_APP_PREDICTOR:
23269 return filterOnlySystemPackages(mAppPredictionServicePackage);
23270 case PackageManagerInternal.PACKAGE_TELEPHONY:
23271 return filterOnlySystemPackages(mTelephonyPackages);
23272 case PackageManagerInternal.PACKAGE_COMPANION:
23273 return filterOnlySystemPackages("com.android.companiondevicemanager");
23274 case PackageManagerInternal.PACKAGE_RETAIL_DEMO:
23275 return TextUtils.isEmpty(mRetailDemoPackage)
23276 ? ArrayUtils.emptyArray(String.class)
23277 : new String[] {mRetailDemoPackage};
23279 return ArrayUtils.emptyArray(String.class);
23284 public boolean isResolveActivityComponent(ComponentInfo component) {
23285 return mResolveActivity.packageName.equals(component.packageName)
23286 && mResolveActivity.name.equals(component.name);
23290 public void setKeepUninstalledPackages(final List<String> packageList) {
23291 Preconditions.checkNotNull(packageList);
23292 List<String> removedFromList = null;
23293 synchronized (mLock) {
23294 if (mKeepUninstalledPackages != null) {
23295 final int packagesCount = mKeepUninstalledPackages.size();
23296 for (int i = 0; i < packagesCount; i++) {
23297 String oldPackage = mKeepUninstalledPackages.get(i);
23298 if (packageList != null && packageList.contains(oldPackage)) {
23301 if (removedFromList == null) {
23302 removedFromList = new ArrayList<>();
23304 removedFromList.add(oldPackage);
23307 mKeepUninstalledPackages = new ArrayList<>(packageList);
23308 if (removedFromList != null) {
23309 final int removedCount = removedFromList.size();
23310 for (int i = 0; i < removedCount; i++) {
23311 deletePackageIfUnusedLPr(removedFromList.get(i));
23318 public boolean isPermissionsReviewRequired(String packageName, int userId) {
23319 synchronized (mLock) {
23320 final AndroidPackage pkg = mPackages.get(packageName);
23325 return mPermissionManager.isPermissionsReviewRequired(pkg, userId);
23330 public PackageInfo getPackageInfo(
23331 String packageName, int flags, int filterCallingUid, int userId) {
23332 return PackageManagerService.this
23333 .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
23334 flags, filterCallingUid, userId);
23338 public long getCeDataInode(String packageName, int userId) {
23339 synchronized (mLock) {
23340 final PackageSetting ps = mSettings.mPackages.get(packageName);
23342 return ps.getCeDataInode(userId);
23349 public Bundle getSuspendedPackageLauncherExtras(String packageName, int userId) {
23350 synchronized (mLock) {
23351 final PackageSetting ps = mSettings.mPackages.get(packageName);
23352 final Bundle allExtras = new Bundle();
23354 final PackageUserState pus = ps.readUserState(userId);
23355 if (pus.suspended) {
23356 for (int i = 0; i < pus.suspendParams.size(); i++) {
23357 final PackageUserState.SuspendParams params =
23358 pus.suspendParams.valueAt(i);
23359 if (params != null && params.launcherExtras != null) {
23360 allExtras.putAll(params.launcherExtras);
23366 return (allExtras.size() > 0) ? allExtras : null;
23371 public boolean isPackageSuspended(String packageName, int userId) {
23372 synchronized (mLock) {
23373 final PackageSetting ps = mSettings.mPackages.get(packageName);
23374 return (ps != null) ? ps.getSuspended(userId) : false;
23379 public void removeAllNonSystemPackageSuspensions(int userId) {
23380 final String[] allPackages;
23381 synchronized (mLock) {
23382 allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
23384 PackageManagerService.this.removeSuspensionsBySuspendingPackage(allPackages,
23385 (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
23390 public void removeNonSystemPackageSuspensions(String packageName, int userId) {
23391 PackageManagerService.this.removeSuspensionsBySuspendingPackage(
23392 new String[]{packageName},
23393 (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
23398 public void flushPackageRestrictions(int userId) {
23399 synchronized (mLock) {
23400 PackageManagerService.this.flushPackageRestrictionsAsUserInternalLocked(userId);
23405 public void removeDistractingPackageRestrictions(String packageName, int userId) {
23406 PackageManagerService.this.removeDistractingPackageRestrictions(
23407 new String[]{packageName}, userId);
23411 public void removeAllDistractingPackageRestrictions(int userId) {
23412 PackageManagerService.this.removeAllDistractingPackageRestrictions(userId);
23416 public String getSuspendingPackage(String suspendedPackage, int userId) {
23417 synchronized (mLock) {
23418 final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
23420 final PackageUserState pus = ps.readUserState(userId);
23421 if (pus.suspended) {
23422 String suspendingPackage = null;
23423 for (int i = 0; i < pus.suspendParams.size(); i++) {
23424 suspendingPackage = pus.suspendParams.keyAt(i);
23425 if (PLATFORM_PACKAGE_NAME.equals(suspendingPackage)) {
23426 return suspendingPackage;
23429 return suspendingPackage;
23437 public SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage,
23438 String suspendingPackage, int userId) {
23439 synchronized (mLock) {
23440 final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
23442 final PackageUserState pus = ps.readUserState(userId);
23443 if (pus.suspended) {
23444 final PackageUserState.SuspendParams suspendParams =
23445 pus.suspendParams.get(suspendingPackage);
23446 return (suspendParams != null) ? suspendParams.dialogInfo : null;
23454 public int getDistractingPackageRestrictions(String packageName, int userId) {
23455 synchronized (mLock) {
23456 final PackageSetting ps = mSettings.mPackages.get(packageName);
23457 return (ps != null) ? ps.getDistractionFlags(userId) : RESTRICTION_NONE;
23462 public int getPackageUid(String packageName, int flags, int userId) {
23463 return PackageManagerService.this
23464 .getPackageUid(packageName, flags, userId);
23468 public int getPackageUidInternal(String packageName, int flags, int userId) {
23469 return PackageManagerService.this
23470 .getPackageUidInternal(packageName, flags, userId, Process.SYSTEM_UID);
23474 public ApplicationInfo getApplicationInfo(
23475 String packageName, int flags, int filterCallingUid, int userId) {
23476 return PackageManagerService.this
23477 .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
23481 public ActivityInfo getActivityInfo(
23482 ComponentName component, int flags, int filterCallingUid, int userId) {
23483 return PackageManagerService.this
23484 .getActivityInfoInternal(component, flags, filterCallingUid, userId);
23488 public List<ResolveInfo> queryIntentActivities(
23489 Intent intent, String resolvedType, int flags, int filterCallingUid, int userId) {
23490 return PackageManagerService.this
23491 .queryIntentActivitiesInternal(intent, resolvedType, flags, 0, filterCallingUid,
23492 userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
23496 public List<ResolveInfo> queryIntentServices(
23497 Intent intent, int flags, int callingUid, int userId) {
23498 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23499 return PackageManagerService.this
23500 .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
23505 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23507 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
23511 public ComponentName getDefaultHomeActivity(int userId) {
23512 return PackageManagerService.this.getDefaultHomeActivity(userId);
23516 public ComponentName getSystemUiServiceComponent() {
23517 return ComponentName.unflattenFromString(mContext.getResources().getString(
23518 com.android.internal.R.string.config_systemUIServiceComponent));
23522 public void setDeviceAndProfileOwnerPackages(
23523 int deviceOwnerUserId, String deviceOwnerPackage,
23524 SparseArray<String> profileOwnerPackages) {
23525 mProtectedPackages.setDeviceAndProfileOwnerPackages(
23526 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
23528 final ArraySet<Integer> usersWithPoOrDo = new ArraySet<>();
23529 if (deviceOwnerPackage != null) {
23530 usersWithPoOrDo.add(deviceOwnerUserId);
23532 final int sz = profileOwnerPackages.size();
23533 for (int i = 0; i < sz; i++) {
23534 if (profileOwnerPackages.valueAt(i) != null) {
23535 usersWithPoOrDo.add(profileOwnerPackages.keyAt(i));
23541 public void setDeviceOwnerProtectedPackages(List<String> packageNames) {
23542 mProtectedPackages.setDeviceOwnerProtectedPackages(packageNames);
23546 public boolean isPackageDataProtected(int userId, String packageName) {
23547 return mProtectedPackages.isPackageDataProtected(userId, packageName);
23551 public boolean isPackageStateProtected(String packageName, int userId) {
23552 return mProtectedPackages.isPackageStateProtected(userId, packageName);
23556 public boolean isPackageEphemeral(int userId, String packageName) {
23557 synchronized (mLock) {
23558 final PackageSetting ps = mSettings.mPackages.get(packageName);
23559 return ps != null ? ps.getInstantApp(userId) : false;
23564 public boolean wasPackageEverLaunched(String packageName, int userId) {
23565 synchronized (mLock) {
23566 return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23571 public boolean isEnabledAndMatches(ParsedMainComponent component, int flags, int userId) {
23572 synchronized (mLock) {
23573 AndroidPackage pkg = getPackage(component.getPackageName());
23574 return mSettings.isEnabledAndMatchLPr(pkg, component, flags, userId);
23579 public boolean userNeedsBadging(int userId) {
23580 synchronized (mLock) {
23581 return PackageManagerService.this.userNeedsBadging(userId);
23586 public String getNameForUid(int uid) {
23587 return PackageManagerService.this.getNameForUid(uid);
23591 public boolean setInstalled(AndroidPackage pkg, @UserIdInt int userId,
23592 boolean installed) {
23593 synchronized (mLock) {
23594 final PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
23595 if (ps.getInstalled(userId) != installed) {
23596 ps.setInstalled(installed, userId);
23604 public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23605 Intent origIntent, String resolvedType, String callingPackage,
23606 @Nullable String callingFeatureId, boolean isRequesterInstantApp,
23607 Bundle verificationBundle, int userId) {
23608 PackageManagerService.this.requestInstantAppResolutionPhaseTwo(responseObj, origIntent,
23609 resolvedType, callingPackage, callingFeatureId, isRequesterInstantApp,
23610 verificationBundle, userId);
23614 public void grantImplicitAccess(int userId, Intent intent,
23615 int recipientAppId, int visibleUid, boolean direct) {
23616 synchronized (mLock) {
23617 final AndroidPackage visiblePackage = getPackage(visibleUid);
23618 final int recipientUid = UserHandle.getUid(userId, recipientAppId);
23619 if (visiblePackage == null || getPackage(recipientUid) == null) {
23623 final boolean instantApp =
23624 isInstantAppInternal(visiblePackage.getPackageName(), userId, visibleUid);
23627 // if the interaction that lead to this granting access to an instant app
23628 // was indirect (i.e.: URI permission grant), do not actually execute the
23632 mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23633 recipientAppId, UserHandle.getAppId(visibleUid) /*instantAppId*/);
23635 mAppsFilter.grantImplicitAccess(recipientUid, visibleUid);
23641 public boolean isInstantAppInstallerComponent(ComponentName component) {
23642 synchronized (mLock) {
23643 return mInstantAppInstallerActivity != null
23644 && mInstantAppInstallerActivity.getComponentName().equals(component);
23649 public void pruneInstantApps() {
23650 mInstantAppRegistry.pruneInstantApps();
23654 public String getSetupWizardPackageName() {
23655 return mSetupWizardPackage;
23658 public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23659 if (policy != null) {
23660 mExternalSourcesPolicy = policy;
23665 public boolean isPackagePersistent(String packageName) {
23666 synchronized (mLock) {
23667 AndroidPackage pkg = mPackages.get(packageName);
23668 return pkg != null && pkg.isSystem() && pkg.isPersistent();
23673 public boolean isLegacySystemApp(AndroidPackage pkg) {
23674 synchronized (mLock) {
23675 final PackageSetting ps = getPackageSetting(pkg.getPackageName());
23676 return mPromoteSystemApps
23678 && mExistingSystemPackages.contains(ps.name);
23683 public List<PackageInfo> getOverlayPackages(int userId) {
23684 final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
23685 synchronized (mLock) {
23686 for (AndroidPackage p : mPackages.values()) {
23687 if (p.getOverlayTarget() != null) {
23688 PackageInfo pkg = generatePackageInfo(getPackageSetting(p.getPackageName()),
23691 overlayPackages.add(pkg);
23696 return overlayPackages;
23700 public List<String> getTargetPackageNames(int userId) {
23701 List<String> targetPackages = new ArrayList<>();
23702 synchronized (mLock) {
23703 for (AndroidPackage p : mPackages.values()) {
23704 if (p.getOverlayTarget() == null) {
23705 targetPackages.add(p.getPackageName());
23709 return targetPackages;
23713 public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
23714 @Nullable List<String> overlayPackageNames,
23715 @NonNull Collection<String> outUpdatedPackageNames) {
23716 synchronized (mLock) {
23717 final AndroidPackage targetPkg = mPackages.get(targetPackageName);
23718 if (targetPackageName == null || targetPkg == null) {
23719 Slog.e(TAG, "failed to find package " + targetPackageName);
23722 ArrayList<String> overlayPaths = null;
23723 if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
23724 final int N = overlayPackageNames.size();
23725 overlayPaths = new ArrayList<>(N);
23726 for (int i = 0; i < N; i++) {
23727 final String packageName = overlayPackageNames.get(i);
23728 final AndroidPackage pkg = mPackages.get(packageName);
23730 Slog.e(TAG, "failed to find package " + packageName);
23733 overlayPaths.add(pkg.getBaseCodePath());
23737 ArraySet<String> updatedPackageNames = null;
23738 if (targetPkg.getLibraryNames() != null) {
23739 // Set the overlay paths for dependencies of the shared library.
23740 updatedPackageNames = new ArraySet<>();
23741 for (String libName : targetPkg.getLibraryNames()) {
23742 final SharedLibraryInfo info = getSharedLibraryInfoLPr(libName,
23743 SharedLibraryInfo.VERSION_UNDEFINED);
23744 if (info == null) {
23747 final List<VersionedPackage> dependents = getPackagesUsingSharedLibraryLPr(
23749 if (dependents == null) {
23752 for (VersionedPackage dependent : dependents) {
23753 final PackageSetting ps = mSettings.mPackages.get(
23754 dependent.getPackageName());
23758 ps.setOverlayPathsForLibrary(libName, overlayPaths, userId);
23759 updatedPackageNames.add(dependent.getPackageName());
23764 final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
23765 ps.setOverlayPaths(overlayPaths, userId);
23767 outUpdatedPackageNames.add(targetPackageName);
23768 if (updatedPackageNames != null) {
23769 outUpdatedPackageNames.addAll(updatedPackageNames);
23777 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23778 int flags, int privateResolveFlags, int userId, boolean resolveForStart,
23779 int filterCallingUid) {
23780 return resolveIntentInternal(
23781 intent, resolvedType, flags, privateResolveFlags, userId, resolveForStart,
23786 public ResolveInfo resolveService(Intent intent, String resolvedType,
23787 int flags, int userId, int callingUid) {
23788 return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
23792 public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
23793 return PackageManagerService.this.resolveContentProviderInternal(
23794 name, flags, userId);
23798 public void addIsolatedUid(int isolatedUid, int ownerUid) {
23799 synchronized (mLock) {
23800 mIsolatedOwners.put(isolatedUid, ownerUid);
23805 public void removeIsolatedUid(int isolatedUid) {
23806 synchronized (mLock) {
23807 mIsolatedOwners.delete(isolatedUid);
23812 public int getUidTargetSdkVersion(int uid) {
23813 synchronized (mLock) {
23814 return getUidTargetSdkVersionLockedLPr(uid);
23819 public int getPackageTargetSdkVersion(String packageName) {
23820 synchronized (mLock) {
23821 return getPackageTargetSdkVersionLockedLPr(packageName);
23826 public boolean canAccessInstantApps(int callingUid, int userId) {
23827 return PackageManagerService.this.canViewInstantApps(callingUid, userId);
23831 public boolean canAccessComponent(int callingUid, ComponentName component, int userId) {
23832 synchronized (mLock) {
23833 final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
23834 return ps != null && !PackageManagerService.this.shouldFilterApplicationLocked(
23835 ps, callingUid, component, TYPE_UNKNOWN, userId);
23840 public boolean hasInstantApplicationMetadata(String packageName, int userId) {
23841 synchronized (mLock) {
23842 return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
23847 public void notifyPackageUse(String packageName, int reason) {
23848 synchronized (mLock) {
23849 PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
23854 public SparseArray<String> getAppsWithSharedUserIds() {
23855 synchronized (mLock) {
23856 return getAppsWithSharedUserIdsLocked();
23862 public String[] getSharedUserPackagesForPackage(String packageName, int userId) {
23863 synchronized (mLock) {
23864 return getSharedUserPackagesForPackageLocked(packageName, userId);
23869 public ArrayMap<String, ProcessInfo> getProcessesForUid(int uid) {
23870 synchronized (mLock) {
23871 return getProcessesForUidLocked(uid);
23876 public int[] getPermissionGids(String permissionName, int userId) {
23877 synchronized (mLock) {
23878 return getPermissionGidsLocked(permissionName, userId);
23883 public boolean isOnlyCoreApps() {
23884 return PackageManagerService.this.isOnlyCoreApps();
23888 public void freeStorage(String volumeUuid, long bytes, int storageFlags)
23889 throws IOException {
23890 PackageManagerService.this.freeStorage(volumeUuid, bytes, storageFlags);
23894 public void forEachPackage(Consumer<AndroidPackage> actionLocked) {
23895 PackageManagerService.this.forEachPackage(actionLocked);
23899 public void forEachPackageSetting(Consumer<PackageSetting> actionLocked) {
23900 synchronized (mLock) {
23901 for (int index = 0; index < mSettings.mPackages.size(); index++) {
23902 actionLocked.accept(mSettings.mPackages.valueAt(index));
23908 public void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> actionLocked,
23909 @UserIdInt int userId) {
23910 PackageManagerService.this.forEachInstalledPackage(actionLocked, userId);
23914 public ArraySet<String> getEnabledComponents(String packageName, int userId) {
23915 synchronized (mLock) {
23916 PackageSetting setting = mSettings.getPackageLPr(packageName);
23917 if (setting == null) {
23918 return new ArraySet<>();
23920 return setting.getEnabledComponents(userId);
23925 public ArraySet<String> getDisabledComponents(String packageName, int userId) {
23926 synchronized (mLock) {
23927 PackageSetting setting = mSettings.getPackageLPr(packageName);
23928 if (setting == null) {
23929 return new ArraySet<>();
23931 return setting.getDisabledComponents(userId);
23936 public @PackageManager.EnabledState int getApplicationEnabledState(
23937 String packageName, int userId) {
23938 synchronized (mLock) {
23939 PackageSetting setting = mSettings.getPackageLPr(packageName);
23940 if (setting == null) {
23941 return COMPONENT_ENABLED_STATE_DEFAULT;
23943 return setting.getEnabled(userId);
23948 public void setEnableRollbackCode(int token, int enableRollbackCode) {
23949 PackageManagerService.this.setEnableRollbackCode(token, enableRollbackCode);
23953 * Ask the package manager to compile layouts in the given package.
23956 public boolean compileLayouts(String packageName) {
23957 AndroidPackage pkg;
23958 synchronized (mLock) {
23959 pkg = mPackages.get(packageName);
23964 return mArtManagerService.compileLayouts(pkg);
23968 public void finishPackageInstall(int token, boolean didLaunch) {
23969 PackageManagerService.this.finishPackageInstall(token, didLaunch);
23974 public String removeLegacyDefaultBrowserPackageName(int userId) {
23975 synchronized (mLock) {
23976 return mSettings.removeDefaultBrowserPackageNameLPw(userId);
23981 public boolean isApexPackage(String packageName) {
23982 return PackageManagerService.this.mApexManager.isApexPackage(packageName);
23986 public List<String> getApksInApex(String apexPackageName) {
23987 return PackageManagerService.this.mApexManager.getApksInApex(apexPackageName);
23991 public void uninstallApex(String packageName, long versionCode, int userId,
23992 IntentSender intentSender, int flags) {
23993 final int callerUid = Binder.getCallingUid();
23994 if (callerUid != Process.ROOT_UID && callerUid != Process.SHELL_UID) {
23995 throw new SecurityException("Not allowed to uninstall apexes");
23997 PackageInstallerService.PackageDeleteObserverAdapter adapter =
23998 new PackageInstallerService.PackageDeleteObserverAdapter(
23999 PackageManagerService.this.mContext, intentSender, packageName,
24001 if ((flags & PackageManager.DELETE_ALL_USERS) == 0) {
24002 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
24003 "Can't uninstall an apex for a single user");
24006 final ApexManager am = PackageManagerService.this.mApexManager;
24007 PackageInfo activePackage = am.getPackageInfo(packageName,
24008 ApexManager.MATCH_ACTIVE_PACKAGE);
24009 if (activePackage == null) {
24010 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
24011 packageName + " is not an apex package");
24014 if (versionCode != PackageManager.VERSION_CODE_HIGHEST
24015 && activePackage.getLongVersionCode() != versionCode) {
24016 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
24017 "Active version " + activePackage.getLongVersionCode()
24018 + " is not equal to " + versionCode + "]");
24021 if (!am.uninstallApex(activePackage.applicationInfo.sourceDir)) {
24022 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
24023 "Failed to uninstall apex " + packageName);
24025 adapter.onPackageDeleted(packageName, PackageManager.DELETE_SUCCEEDED,
24031 public void setRuntimePermissionsFingerPrint(@NonNull String fingerPrint,
24032 @UserIdInt int userId) {
24033 synchronized (mLock) {
24034 mSettings.setRuntimePermissionsFingerPrintLPr(fingerPrint, userId);
24039 public void migrateLegacyObbData() {
24041 mInstaller.migrateLegacyObbData();
24042 } catch (Exception e) {
24048 public void writeSettings(boolean async) {
24049 synchronized (mLock) {
24051 scheduleWriteSettingsLocked();
24053 mSettings.writeLPr();
24059 public void writePermissionSettings(int[] userIds, boolean async) {
24060 synchronized (mLock) {
24061 for (int userId : userIds) {
24062 mSettings.writeRuntimePermissionsForUserLPr(userId, !async);
24068 public boolean isCallerInstallerOfRecord(
24069 @NonNull AndroidPackage pkg, int callingUid) {
24070 synchronized (mLock) {
24074 final PackageSetting packageSetting = getPackageSetting(pkg.getPackageName());
24075 if (packageSetting == null) {
24078 final PackageSetting installerPackageSetting =
24079 mSettings.mPackages.get(packageSetting.installSource.installerPackageName);
24080 return installerPackageSetting != null
24081 && UserHandle.isSameApp(installerPackageSetting.appId, callingUid);
24086 public boolean areDefaultRuntimePermissionsGranted(int userId) {
24087 synchronized (mLock) {
24088 return mSettings.areDefaultRuntimePermissionsGrantedLPr(userId);
24093 public void setReadExternalStorageEnforced(boolean enforced) {
24094 synchronized (mLock) {
24095 if (mSettings.mReadExternalStorageEnforced != null
24096 && mSettings.mReadExternalStorageEnforced == enforced) {
24099 mSettings.mReadExternalStorageEnforced = enforced ? Boolean.TRUE : Boolean.FALSE;
24100 mSettings.writeLPr();
24105 public void setIntegrityVerificationResult(int verificationId, int verificationResult) {
24106 final Message msg = mHandler.obtainMessage(INTEGRITY_VERIFICATION_COMPLETE);
24107 msg.arg1 = verificationId;
24108 msg.obj = verificationResult;
24109 mHandler.sendMessage(msg);
24113 public List<String> getMimeGroup(String packageName, String mimeGroup) {
24114 return PackageManagerService.this.getMimeGroup(packageName, mimeGroup);
24118 @GuardedBy("mLock")
24119 private SparseArray<String> getAppsWithSharedUserIdsLocked() {
24120 final SparseArray<String> sharedUserIds = new SparseArray<>();
24121 synchronized (mLock) {
24122 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
24123 sharedUserIds.put(UserHandle.getAppId(setting.userId), setting.name);
24126 return sharedUserIds;
24129 @GuardedBy("mLock")
24131 private String[] getSharedUserPackagesForPackageLocked(String packageName, int userId) {
24132 final PackageSetting packageSetting = mSettings.mPackages.get(packageName);
24133 if (packageSetting == null || !packageSetting.isSharedUser()) {
24134 return EmptyArray.STRING;
24137 ArraySet<PackageSetting> packages = packageSetting.sharedUser.packages;
24138 String[] res = new String[packages.size()];
24139 final Iterator<PackageSetting> it = packages.iterator();
24141 while (it.hasNext()) {
24142 PackageSetting ps = it.next();
24143 if (ps.getInstalled(userId)) {
24144 res[i++] = ps.name;
24147 res = ArrayUtils.trimToSize(res, i);
24148 return res != null ? res : EmptyArray.STRING;
24151 @GuardedBy("mLock")
24152 public ArrayMap<String, ProcessInfo> getProcessesForUidLocked(int uid) {
24153 final int appId = UserHandle.getAppId(uid);
24154 final SettingBase obj = mSettings.getSettingLPr(appId);
24155 if (obj instanceof SharedUserSetting) {
24156 final SharedUserSetting sus = (SharedUserSetting) obj;
24157 return PackageInfoUtils.generateProcessInfo(sus.processes, 0);
24158 } else if (obj instanceof PackageSetting) {
24159 final PackageSetting ps = (PackageSetting) obj;
24160 return PackageInfoUtils.generateProcessInfo(ps.pkg.getProcesses(), 0);
24165 @GuardedBy("mLock")
24166 public int[] getPermissionGidsLocked(String permissionName, int userId) {
24167 BasePermission perm
24168 = mPermissionManager.getPermissionSettings().getPermission(permissionName);
24169 if (perm != null) {
24170 return perm.computeGids(userId);
24176 public int getRuntimePermissionsVersion(@UserIdInt int userId) {
24177 Preconditions.checkArgumentNonnegative(userId);
24178 enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
24179 "getRuntimePermissionVersion");
24180 synchronized (mLock) {
24181 return mSettings.getDefaultRuntimePermissionsVersionLPr(userId);
24186 public void setRuntimePermissionsVersion(int version, @UserIdInt int userId) {
24187 Preconditions.checkArgumentNonnegative(version);
24188 Preconditions.checkArgumentNonnegative(userId);
24189 enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
24190 "setRuntimePermissionVersion");
24191 synchronized (mLock) {
24192 mSettings.setDefaultRuntimePermissionsVersionLPr(version, userId);
24196 private void enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
24197 @NonNull String message) {
24198 if (mContext.checkCallingOrSelfPermission(
24199 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY)
24200 != PackageManager.PERMISSION_GRANTED
24201 && mContext.checkCallingOrSelfPermission(
24202 Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS)
24203 != PackageManager.PERMISSION_GRANTED) {
24204 throw new SecurityException(message + " requires "
24205 + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " or "
24206 + Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS);
24211 public PackageSetting getPackageSetting(String packageName) {
24212 return getPackageSettingInternal(packageName, Binder.getCallingUid());
24215 private PackageSetting getPackageSettingInternal(String packageName, int callingUid) {
24216 synchronized (mLock) {
24217 packageName = resolveInternalPackageNameInternalLocked(
24218 packageName, PackageManager.VERSION_CODE_HIGHEST, callingUid);
24219 return mSettings.mPackages.get(packageName);
24223 void forEachPackage(Consumer<AndroidPackage> actionLocked) {
24224 synchronized (mLock) {
24225 int numPackages = mPackages.size();
24226 for (int i = 0; i < numPackages; i++) {
24227 actionLocked.accept(mPackages.valueAt(i));
24232 void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> actionLocked,
24233 @UserIdInt int userId) {
24234 synchronized (mLock) {
24235 int numPackages = mPackages.size();
24236 for (int i = 0; i < numPackages; i++) {
24237 AndroidPackage pkg = mPackages.valueAt(i);
24238 PackageSetting setting = mSettings.getPackageLPr(pkg.getPackageName());
24239 if (setting == null || !setting.getInstalled(userId)) {
24242 actionLocked.accept(pkg);
24247 boolean isHistoricalPackageUsageAvailable() {
24248 return mPackageUsage.isHistoricalPackageUsageAvailable();
24252 * Return a <b>copy</b> of the collection of packages known to the package manager.
24253 * @return A copy of the values of mPackages.
24255 Collection<AndroidPackage> getPackages() {
24256 synchronized (mLock) {
24257 return new ArrayList<>(mPackages.values());
24262 * Logs process start information (including base APK hash) to the security log.
24266 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
24267 String apkFile, int pid) {
24268 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24271 if (!SecurityLog.isLoggingEnabled()) {
24274 Bundle data = new Bundle();
24275 data.putLong("startTimestamp", System.currentTimeMillis());
24276 data.putString("processName", processName);
24277 data.putInt("uid", uid);
24278 data.putString("seinfo", seinfo);
24279 data.putString("apkFile", apkFile);
24280 data.putInt("pid", pid);
24281 Message msg = mProcessLoggingHandler.obtainMessage(
24282 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
24284 mProcessLoggingHandler.sendMessage(msg);
24287 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
24288 return mCompilerStats.getPackageStats(pkgName);
24291 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(AndroidPackage pkg) {
24292 return getOrCreateCompilerPackageStats(pkg.getPackageName());
24295 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
24296 return mCompilerStats.getOrCreatePackageStats(pkgName);
24299 public void deleteCompilerPackageStats(String pkgName) {
24300 mCompilerStats.deletePackageStats(pkgName);
24304 public int getInstallReason(String packageName, int userId) {
24305 final int callingUid = Binder.getCallingUid();
24306 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24307 true /* requireFullPermission */, false /* checkShell */,
24308 "get install reason");
24309 synchronized (mLock) {
24310 final PackageSetting ps = mSettings.mPackages.get(packageName);
24311 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
24312 return PackageManager.INSTALL_REASON_UNKNOWN;
24315 return ps.getInstallReason(userId);
24318 return PackageManager.INSTALL_REASON_UNKNOWN;
24322 public boolean canRequestPackageInstalls(String packageName, int userId) {
24323 return canRequestPackageInstallsInternal(packageName, 0, userId,
24324 true /* throwIfPermNotDeclared*/);
24327 private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
24328 boolean throwIfPermNotDeclared) {
24329 int callingUid = Binder.getCallingUid();
24330 int uid = getPackageUid(packageName, 0, userId);
24331 if (callingUid != uid && callingUid != Process.ROOT_UID
24332 && callingUid != Process.SYSTEM_UID) {
24333 throw new SecurityException(
24334 "Caller uid " + callingUid + " does not own package " + packageName);
24336 ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
24337 if (info == null) {
24340 if (info.targetSdkVersion < Build.VERSION_CODES.O) {
24343 if (isInstantApp(packageName, userId)) {
24346 String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
24347 String[] packagesDeclaringPermission =
24348 mPermissionManager.getAppOpPermissionPackages(appOpPermission, callingUid);
24349 if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
24350 if (throwIfPermNotDeclared) {
24351 throw new SecurityException("Need to declare " + appOpPermission
24352 + " to call this api");
24354 Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
24358 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)
24359 || mUserManager.hasUserRestriction(
24360 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, userId)) {
24363 if (mExternalSourcesPolicy != null) {
24364 int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
24365 return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
24371 public ComponentName getInstantAppResolverSettingsComponent() {
24372 return mInstantAppResolverSettingsComponent;
24376 public ComponentName getInstantAppInstallerComponent() {
24377 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24380 return mInstantAppInstallerActivity == null
24381 ? null : mInstantAppInstallerActivity.getComponentName();
24385 public String getInstantAppAndroidId(String packageName, int userId) {
24386 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
24387 "getInstantAppAndroidId");
24388 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
24389 true /* requireFullPermission */, false /* checkShell */,
24390 "getInstantAppAndroidId");
24391 // Make sure the target is an Instant App.
24392 if (!isInstantApp(packageName, userId)) {
24395 synchronized (mLock) {
24396 return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
24400 boolean canHaveOatDir(String packageName) {
24401 synchronized (mLock) {
24402 AndroidPackage p = mPackages.get(packageName);
24403 PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
24404 if (p == null || pkgSetting == null) {
24407 return AndroidPackageUtils.canHaveOatDir(p,
24408 pkgSetting.getPkgState().isUpdatedSystemApp());
24412 private String getOatDir(AndroidPackage pkg, @NonNull PackageSetting pkgSetting) {
24413 if (!AndroidPackageUtils.canHaveOatDir(pkg,
24414 pkgSetting.getPkgState().isUpdatedSystemApp())) {
24417 File codePath = new File(pkg.getCodePath());
24418 if (codePath.isDirectory()) {
24419 return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
24424 void deleteOatArtifactsOfPackage(String packageName) {
24425 final String[] instructionSets;
24426 final List<String> codePaths;
24427 final String oatDir;
24428 final AndroidPackage pkg;
24429 final PackageSetting pkgSetting;
24430 synchronized (mLock) {
24431 pkg = mPackages.get(packageName);
24432 pkgSetting = mSettings.getPackageLPr(packageName);
24434 instructionSets = getAppDexInstructionSets(
24435 AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting),
24436 AndroidPackageUtils.getSecondaryCpuAbi(pkg, pkgSetting));
24437 codePaths = AndroidPackageUtils.getAllCodePaths(pkg);
24438 oatDir = getOatDir(pkg, pkgSetting);
24440 for (String codePath : codePaths) {
24441 for (String isa : instructionSets) {
24443 mInstaller.deleteOdex(codePath, isa, oatDir);
24444 } catch (InstallerException e) {
24445 Log.e(TAG, "Failed deleting oat files for " + codePath, e);
24451 Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
24452 Set<String> unusedPackages = new HashSet<>();
24453 long currentTimeInMillis = System.currentTimeMillis();
24454 synchronized (mLock) {
24455 for (AndroidPackage pkg : mPackages.values()) {
24456 PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
24460 PackageDexUsage.PackageUseInfo packageUseInfo =
24461 getDexManager().getPackageUseInfoOrDefault(pkg.getPackageName());
24462 if (PackageManagerServiceUtils
24463 .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
24464 downgradeTimeThresholdMillis, packageUseInfo,
24465 ps.getPkgState().getLatestPackageUseTimeInMills(),
24466 ps.getPkgState().getLatestForegroundPackageUseTimeInMills())) {
24467 unusedPackages.add(pkg.getPackageName());
24471 return unusedPackages;
24475 public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
24477 final int callingUid = Binder.getCallingUid();
24478 final int callingAppId = UserHandle.getAppId(callingUid);
24480 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24481 true /*requireFullPermission*/, true /*checkShell*/, "setHarmfulAppInfo");
24483 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
24484 checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
24485 throw new SecurityException("Caller must have the "
24486 + SET_HARMFUL_APP_WARNINGS + " permission.");
24489 synchronized (mLock) {
24490 mSettings.setHarmfulAppWarningLPw(packageName, warning, userId);
24491 scheduleWritePackageRestrictionsLocked(userId);
24497 public CharSequence getHarmfulAppWarning(@NonNull String packageName, int userId) {
24498 final int callingUid = Binder.getCallingUid();
24499 final int callingAppId = UserHandle.getAppId(callingUid);
24501 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24502 true /*requireFullPermission*/, true /*checkShell*/, "getHarmfulAppInfo");
24504 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
24505 checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
24506 throw new SecurityException("Caller must have the "
24507 + SET_HARMFUL_APP_WARNINGS + " permission.");
24510 synchronized (mLock) {
24511 return mSettings.getHarmfulAppWarningLPr(packageName, userId);
24516 public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) {
24517 final int callingUid = Binder.getCallingUid();
24518 final int callingAppId = UserHandle.getAppId(callingUid);
24520 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24521 false /*requireFullPermission*/, true /*checkShell*/, "isPackageStateProtected");
24523 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID
24524 && checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid) != PERMISSION_GRANTED) {
24525 throw new SecurityException("Caller must have the "
24526 + MANAGE_DEVICE_ADMINS + " permission.");
24529 return mProtectedPackages.isPackageStateProtected(userId, packageName);
24533 public void sendDeviceCustomizationReadyBroadcast() {
24534 mContext.enforceCallingPermission(Manifest.permission.SEND_DEVICE_CUSTOMIZATION_READY,
24535 "sendDeviceCustomizationReadyBroadcast");
24537 final long ident = Binder.clearCallingIdentity();
24539 final Intent intent = new Intent(Intent.ACTION_DEVICE_CUSTOMIZATION_READY);
24540 intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
24541 final IActivityManager am = ActivityManager.getService();
24542 final String[] requiredPermissions = {
24543 Manifest.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY,
24546 am.broadcastIntentWithFeature(null, null, intent, null, null, 0, null, null,
24547 requiredPermissions, android.app.AppOpsManager.OP_NONE, null, false, false,
24548 UserHandle.USER_ALL);
24549 } catch (RemoteException e) {
24550 throw e.rethrowFromSystemServer();
24553 Binder.restoreCallingIdentity(ident);
24557 private void applyMimeGroupChanges(String packageName, String mimeGroup) {
24558 if (mComponentResolver.updateMimeGroup(packageName, mimeGroup)) {
24559 clearPackagePreferredActivities(packageName, UserHandle.USER_ALL);
24562 mPmInternal.writeSettings(false);
24566 public void setMimeGroup(String packageName, String mimeGroup, List<String> mimeTypes) {
24567 boolean changed = mSettings.mPackages.get(packageName)
24568 .setMimeGroup(mimeGroup, mimeTypes);
24571 applyMimeGroupChanges(packageName, mimeGroup);
24576 public void clearMimeGroup(String packageName, String mimeGroup) {
24577 boolean changed = mSettings.mPackages.get(packageName).clearMimeGroup(mimeGroup);
24580 applyMimeGroupChanges(packageName, mimeGroup);
24585 public List<String> getMimeGroup(String packageName, String mimeGroup) {
24586 return mSettings.mPackages.get(packageName).getMimeGroup(mimeGroup);
24589 static class ActiveInstallSession {
24590 private final String mPackageName;
24591 private final File mStagedDir;
24592 private final IPackageInstallObserver2 mObserver;
24593 private final PackageInstaller.SessionParams mSessionParams;
24594 private final int mInstallerUid;
24595 @NonNull private final InstallSource mInstallSource;
24596 private final UserHandle mUser;
24597 private final SigningDetails mSigningDetails;
24599 ActiveInstallSession(String packageName, File stagedDir, IPackageInstallObserver2 observer,
24600 PackageInstaller.SessionParams sessionParams, int installerUid,
24601 InstallSource installSource, UserHandle user, SigningDetails signingDetails) {
24602 mPackageName = packageName;
24603 mStagedDir = stagedDir;
24604 mObserver = observer;
24605 mSessionParams = sessionParams;
24606 mInstallerUid = installerUid;
24607 mInstallSource = Preconditions.checkNotNull(installSource);
24609 mSigningDetails = signingDetails;
24612 public String getPackageName() {
24613 return mPackageName;
24616 public File getStagedDir() {
24620 public IPackageInstallObserver2 getObserver() {
24624 public PackageInstaller.SessionParams getSessionParams() {
24625 return mSessionParams;
24628 public int getInstallerUid() {
24629 return mInstallerUid;
24633 public InstallSource getInstallSource() {
24634 return mInstallSource;
24637 public UserHandle getUser() {
24641 public SigningDetails getSigningDetails() {
24642 return mSigningDetails;
24647 interface PackageSender {
24649 * @param userIds User IDs where the action occurred on a full application
24650 * @param instantUserIds User IDs where the action occurred on an instant application
24652 void sendPackageBroadcast(final String action, final String pkg,
24653 final Bundle extras, final int flags, final String targetPkg,
24654 final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds);
24655 void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
24656 boolean includeStopped, int appId, int[] userIds, int[] instantUserIds);
24657 void notifyPackageAdded(String packageName, int uid);
24658 void notifyPackageChanged(String packageName, int uid);
24659 void notifyPackageRemoved(String packageName, int uid);