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 int sessionId = msg.arg2;
1971 final InstallParams params = mPendingEnableRollback.get(enableRollbackToken);
1972 if (params != null) {
1973 final InstallArgs args = params.mArgs;
1974 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1976 Slog.w(TAG, "Enable rollback timed out for " + originUri);
1977 mPendingEnableRollback.remove(enableRollbackToken);
1979 Slog.w(TAG, "Continuing with installation of " + originUri);
1980 Trace.asyncTraceEnd(
1981 TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
1982 params.handleRollbackEnabled();
1983 Intent rollbackTimeoutIntent = new Intent(
1984 Intent.ACTION_CANCEL_ENABLE_ROLLBACK);
1985 rollbackTimeoutIntent.putExtra(
1986 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_SESSION_ID,
1988 rollbackTimeoutIntent.addFlags(
1989 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1990 mContext.sendBroadcastAsUser(rollbackTimeoutIntent, UserHandle.SYSTEM,
1991 android.Manifest.permission.PACKAGE_ROLLBACK_AGENT);
1999 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
2000 boolean killApp, boolean virtualPreload,
2001 String[] grantedPermissions, List<String> whitelistedRestrictedPermissions,
2002 boolean launchedForRestore, String installerPackage,
2003 IPackageInstallObserver2 installObserver, int dataLoaderType) {
2004 final boolean succeeded = res.returnCode == PackageManager.INSTALL_SUCCEEDED;
2005 final boolean update = res.removedInfo != null && res.removedInfo.removedPackage != null;
2008 // Send the removed broadcasts
2009 if (res.removedInfo != null) {
2010 res.removedInfo.sendPackageRemovedBroadcasts(killApp);
2013 // Whitelist any restricted permissions first as some may be runtime
2014 // that the installer requested to be granted at install time.
2015 if (whitelistedRestrictedPermissions != null
2016 && !whitelistedRestrictedPermissions.isEmpty()) {
2017 mPermissionManager.setWhitelistedRestrictedPermissions(
2018 res.pkg, res.newUsers, whitelistedRestrictedPermissions,
2019 Process.myUid(), FLAG_PERMISSION_WHITELIST_INSTALLER);
2022 // Now that we successfully installed the package, grant runtime
2023 // permissions if requested before broadcasting the install. Also
2024 // for legacy apps in permission review mode we clear the permission
2025 // review flag which is used to emulate runtime permissions for
2027 if (grantPermissions) {
2028 final int callingUid = Binder.getCallingUid();
2029 mPermissionManager.grantRequestedRuntimePermissions(
2030 res.pkg, res.newUsers, grantedPermissions, callingUid);
2033 final String installerPackageName =
2034 res.installerPackageName != null
2035 ? res.installerPackageName
2036 : res.removedInfo != null
2037 ? res.removedInfo.installerPackageName
2040 synchronized (mLock) {
2041 mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
2044 final String packageName = res.pkg.getPackageName();
2046 // Determine the set of users who are adding this package for
2047 // the first time vs. those who are seeing an update.
2048 int[] firstUserIds = EMPTY_INT_ARRAY;
2049 int[] firstInstantUserIds = EMPTY_INT_ARRAY;
2050 int[] updateUserIds = EMPTY_INT_ARRAY;
2051 int[] instantUserIds = EMPTY_INT_ARRAY;
2052 final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
2053 final PackageSetting ps = getPackageSetting(res.pkg.getPackageName());
2054 for (int newUser : res.newUsers) {
2055 final boolean isInstantApp = ps.getInstantApp(newUser);
2058 firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2060 firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2064 boolean isNew = true;
2065 for (int origUser : res.origUsers) {
2066 if (origUser == newUser) {
2073 firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2075 firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2079 instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
2081 updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
2086 // Send installed broadcasts if the package is not a static shared lib.
2087 if (res.pkg.getStaticSharedLibName() == null) {
2088 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(
2089 res.pkg.getBaseCodePath());
2091 // Send added for users that see the package for the first time
2092 // sendPackageAddedForNewUsers also deals with system apps
2093 int appId = UserHandle.getAppId(res.uid);
2094 boolean isSystem = res.pkg.isSystem();
2095 sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
2096 virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds);
2098 // Send added for users that don't see the package for the first time
2099 Bundle extras = new Bundle(1);
2100 extras.putInt(Intent.EXTRA_UID, res.uid);
2102 extras.putBoolean(Intent.EXTRA_REPLACING, true);
2104 extras.putInt(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType);
2105 // Send to all running apps.
2106 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2107 extras, 0 /*flags*/,
2108 null /*targetPackage*/, null /*finishedReceiver*/,
2109 updateUserIds, instantUserIds);
2110 if (installerPackageName != null) {
2111 // Send to the installer, even if it's not running.
2112 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2113 extras, 0 /*flags*/,
2114 installerPackageName, null /*finishedReceiver*/,
2115 updateUserIds, instantUserIds);
2117 // if the required verifier is defined, but, is not the installer of record
2118 // for the package, it gets notified
2119 final boolean notifyVerifier = mRequiredVerifierPackage != null
2120 && !mRequiredVerifierPackage.equals(installerPackageName);
2121 if (notifyVerifier) {
2122 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2123 extras, 0 /*flags*/,
2124 mRequiredVerifierPackage, null /*finishedReceiver*/,
2125 updateUserIds, instantUserIds);
2127 // If package installer is defined, notify package installer about new
2129 if (mRequiredInstallerPackage != null) {
2130 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2131 extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND /*flags*/,
2132 mRequiredInstallerPackage, null /*finishedReceiver*/,
2133 firstUserIds, instantUserIds);
2136 // Send replaced for users that don't see the package for the first time
2138 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2139 packageName, extras, 0 /*flags*/,
2140 null /*targetPackage*/, null /*finishedReceiver*/,
2141 updateUserIds, instantUserIds);
2142 if (installerPackageName != null) {
2143 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2144 extras, 0 /*flags*/,
2145 installerPackageName, null /*finishedReceiver*/,
2146 updateUserIds, instantUserIds);
2148 if (notifyVerifier) {
2149 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2150 extras, 0 /*flags*/,
2151 mRequiredVerifierPackage, null /*finishedReceiver*/,
2152 updateUserIds, instantUserIds);
2154 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2155 null /*package*/, null /*extras*/, 0 /*flags*/,
2156 packageName /*targetPackage*/,
2157 null /*finishedReceiver*/, updateUserIds, instantUserIds);
2158 } else if (launchedForRestore && !res.pkg.isSystem()) {
2159 // First-install and we did a restore, so we're responsible for the
2160 // first-launch broadcast.
2162 Slog.i(TAG, "Post-restore of " + packageName
2163 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds));
2165 sendFirstLaunchBroadcast(packageName, installerPackage,
2166 firstUserIds, firstInstantUserIds);
2169 // Send broadcast package appeared if external for all users
2170 if (res.pkg.isExternalStorage()) {
2172 final StorageManager storage = mInjector.getStorageManager();
2174 storage.findVolumeByUuid(
2175 res.pkg.getStorageUuid().toString());
2176 int packageExternalStorageType =
2177 getPackageExternalStorageType(volume, res.pkg.isExternalStorage());
2178 // If the package was installed externally, log it.
2179 if (packageExternalStorageType != StorageEnums.UNKNOWN) {
2180 FrameworkStatsLog.write(
2181 FrameworkStatsLog.APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED,
2182 packageExternalStorageType, res.pkg.getPackageName());
2185 if (DEBUG_INSTALL) {
2186 Slog.i(TAG, "upgrading pkg " + res.pkg + " is external");
2188 final int[] uidArray = new int[]{res.pkg.getUid()};
2189 ArrayList<String> pkgList = new ArrayList<>(1);
2190 pkgList.add(packageName);
2191 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2193 } else if (!ArrayUtils.isEmpty(res.libraryConsumers)) { // if static shared lib
2194 for (int i = 0; i < res.libraryConsumers.size(); i++) {
2195 AndroidPackage pkg = res.libraryConsumers.get(i);
2196 // send broadcast that all consumers of the static shared library have changed
2197 sendPackageChangedBroadcast(pkg.getPackageName(), false /* dontKillApp */,
2198 new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
2199 pkg.getUid(), null);
2203 // Work that needs to happen on first install within each user
2204 if (firstUserIds != null && firstUserIds.length > 0) {
2205 for (int userId : firstUserIds) {
2206 // If this app is a browser and it's newly-installed for some
2207 // users, clear any default-browser state in those users. The
2208 // app's nature doesn't depend on the user, so we can just check
2209 // its browser nature in any user and generalize.
2210 if (packageIsBrowser(packageName, userId)) {
2211 // If this browser is restored from user's backup, do not clear
2212 // default-browser state for this user
2213 synchronized (mLock) {
2214 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
2215 if (pkgSetting.getInstallReason(userId)
2216 != PackageManager.INSTALL_REASON_DEVICE_RESTORE) {
2217 mPermissionManager.setDefaultBrowser(null, true, true, userId);
2222 // We may also need to apply pending (restored) runtime permission grants
2223 // within these users.
2224 mPermissionManager.restoreDelayedRuntimePermissions(packageName,
2225 UserHandle.of(userId));
2227 // Persistent preferred activity might have came into effect due to this
2229 updateDefaultHomeNotLocked(userId);
2233 if (allNewUsers && !update) {
2234 notifyPackageAdded(packageName, res.uid);
2236 notifyPackageChanged(packageName, res.uid);
2239 // Log current value of "unknown sources" setting
2240 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2241 getUnknownSourcesSettings());
2243 // Remove the replaced package's older resources safely now
2244 InstallArgs args = res.removedInfo != null ? res.removedInfo.args : null;
2247 // If we didn't kill the app, defer the deletion of code/resource files, since
2248 // they may still be in use by the running application. This mitigates problems
2249 // in cases where resources or code is loaded by a new Activity before
2250 // ApplicationInfo changes have propagated to all application threads.
2251 scheduleDeferredNoKillPostDelete(args);
2253 synchronized (mInstallLock) {
2254 args.doPostDeleteLI(true);
2258 // Force a gc to clear up things. Ask for a background one, it's fine to go on
2259 // and not block here.
2260 VMRuntime.getRuntime().requestConcurrentGC();
2263 // Notify DexManager that the package was installed for new users.
2264 // The updated users should already be indexed and the package code paths
2265 // should not change.
2266 // Don't notify the manager for ephemeral apps as they are not expected to
2267 // survive long enough to benefit of background optimizations.
2268 for (int userId : firstUserIds) {
2269 PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2270 // There's a race currently where some install events may interleave with an
2271 // uninstall. This can lead to package info being null (b/36642664).
2273 mDexManager.notifyPackageInstalled(info, userId);
2278 final boolean deferInstallObserver = succeeded && update && !killApp;
2279 if (deferInstallObserver) {
2280 scheduleDeferredNoKillInstallObserver(res, installObserver);
2282 notifyInstallObserver(res, installObserver);
2287 public void notifyPackagesReplacedReceived(String[] packages) {
2288 final int callingUid = Binder.getCallingUid();
2289 final int callingUserId = UserHandle.getUserId(callingUid);
2291 for (String packageName : packages) {
2292 PackageSetting setting = mSettings.mPackages.get(packageName);
2294 && shouldFilterApplicationLocked(setting, callingUid, callingUserId)) {
2295 notifyInstallObserver(packageName);
2300 private void notifyInstallObserver(String packageName) {
2301 Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
2302 mNoKillInstallObservers.remove(packageName);
2305 notifyInstallObserver(pair.first, pair.second);
2309 private void notifyInstallObserver(PackageInstalledInfo info,
2310 IPackageInstallObserver2 installObserver) {
2311 if (installObserver != null) {
2313 Bundle extras = extrasForInstallResult(info);
2314 installObserver.onPackageInstalled(info.name, info.returnCode,
2315 info.returnMsg, extras);
2316 } catch (RemoteException e) {
2317 Slog.i(TAG, "Observer no longer exists.");
2322 private void scheduleDeferredNoKillPostDelete(InstallArgs args) {
2323 Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_POST_DELETE, args);
2324 mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_POST_DELETE_DELAY_MS);
2327 private void scheduleDeferredNoKillInstallObserver(PackageInstalledInfo info,
2328 IPackageInstallObserver2 observer) {
2329 String packageName = info.pkg.getPackageName();
2330 mNoKillInstallObservers.put(packageName, Pair.create(info, observer));
2331 Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_INSTALL_OBSERVER, packageName);
2332 mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS);
2336 * Gets the type of the external storage a package is installed on.
2337 * @param packageVolume The storage volume of the package.
2338 * @param packageIsExternal true if the package is currently installed on
2339 * external/removable/unprotected storage.
2340 * @return {@link StorageEnums#UNKNOWN} if the package is not stored externally or the
2341 * corresponding {@link StorageEnums} storage type value if it is.
2342 * corresponding {@link StorageEnums} storage type value if it is.
2344 private static int getPackageExternalStorageType(VolumeInfo packageVolume,
2345 boolean packageIsExternal) {
2346 if (packageVolume != null) {
2347 DiskInfo disk = packageVolume.getDisk();
2350 return StorageEnums.SD_CARD;
2353 return StorageEnums.USB;
2355 if (packageIsExternal) {
2356 return StorageEnums.OTHER;
2360 return StorageEnums.UNKNOWN;
2363 private StorageEventListener mStorageListener = new StorageEventListener() {
2365 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2366 if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2367 if (vol.state == VolumeInfo.STATE_MOUNTED) {
2368 final String volumeUuid = vol.getFsUuid();
2370 // Clean up any users or apps that were removed or recreated
2371 // while this volume was missing
2372 mUserManager.reconcileUsers(volumeUuid);
2373 reconcileApps(volumeUuid);
2375 // Clean up any install sessions that expired or were
2376 // cancelled while this volume was missing
2377 mInstallerService.onPrivateVolumeMounted(volumeUuid);
2379 loadPrivatePackages(vol);
2381 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2382 unloadPrivatePackages(vol);
2388 public void onVolumeForgotten(String fsUuid) {
2389 if (TextUtils.isEmpty(fsUuid)) {
2390 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2394 // Remove any apps installed on the forgotten volume
2395 synchronized (mLock) {
2396 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2397 for (PackageSetting ps : packages) {
2398 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2399 deletePackageVersioned(new VersionedPackage(ps.name,
2400 PackageManager.VERSION_CODE_HIGHEST),
2401 new LegacyPackageDeleteObserver(null).getBinder(),
2402 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2403 // Try very hard to release any references to this package
2404 // so we don't risk the system server being killed due to
2406 AttributeCache.instance().removePackage(ps.name);
2409 mSettings.onVolumeForgotten(fsUuid);
2410 mSettings.writeLPr();
2415 Bundle extrasForInstallResult(PackageInstalledInfo res) {
2416 Bundle extras = null;
2417 switch (res.returnCode) {
2418 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2419 extras = new Bundle();
2420 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2421 res.origPermission);
2422 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2426 case PackageManager.INSTALL_SUCCEEDED: {
2427 extras = new Bundle();
2428 extras.putBoolean(Intent.EXTRA_REPLACING,
2429 res.removedInfo != null && res.removedInfo.removedPackage != null);
2436 void scheduleWriteSettingsLocked() {
2437 // We normally invalidate when we write settings, but in cases where we delay and
2438 // coalesce settings writes, this strategy would have us invalidate the cache too late.
2439 // Invalidating on schedule addresses this problem.
2440 PackageManager.invalidatePackageInfoCache();
2441 if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2442 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2446 void scheduleWritePackageListLocked(int userId) {
2447 PackageManager.invalidatePackageInfoCache();
2448 if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2449 Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2451 mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2455 void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2456 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2457 scheduleWritePackageRestrictionsLocked(userId);
2460 void scheduleWritePackageRestrictionsLocked(int userId) {
2461 PackageManager.invalidatePackageInfoCache();
2462 final int[] userIds = (userId == UserHandle.USER_ALL)
2463 ? mUserManager.getUserIds() : new int[]{userId};
2464 for (int nextUserId : userIds) {
2465 if (!mUserManager.exists(nextUserId)) return;
2467 mDirtyUsers.add(nextUserId);
2468 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2469 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2474 public static PackageManagerService main(Context context, Installer installer,
2475 boolean factoryTest, boolean onlyCore) {
2476 // Self-check for initial settings.
2477 PackageManagerServiceCompilerMapping.checkProperties();
2478 final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
2479 Trace.TRACE_TAG_PACKAGE_MANAGER);
2480 t.traceBegin("create package manager");
2481 final Object lock = new Object();
2482 final Object installLock = new Object();
2484 Injector injector = new Injector(
2485 context, lock, installer, installLock, new PackageAbiHelperImpl(),
2487 new ComponentResolver(i.getUserManagerService(), pm.mPmInternal, lock),
2489 PermissionManagerService.create(context, lock),
2491 new UserManagerService(context, pm,
2492 new UserDataPreparer(installer, installLock, context, onlyCore),
2495 new Settings(Environment.getDataDirectory(),
2496 i.getPermissionManagerServiceInternal().getPermissionSettings(),
2498 new Injector.LocalServicesProducer<>(ActivityTaskManagerInternal.class),
2499 new Injector.LocalServicesProducer<>(DeviceIdleInternal.class),
2500 new Injector.LocalServicesProducer<>(StorageManagerInternal.class),
2501 new Injector.LocalServicesProducer<>(NetworkPolicyManagerInternal.class),
2502 new Injector.LocalServicesProducer<>(PermissionPolicyInternal.class),
2503 new Injector.LocalServicesProducer<>(DeviceStorageMonitorInternal.class),
2504 new Injector.SystemServiceProducer<>(DisplayManager.class),
2505 new Injector.SystemServiceProducer<>(StorageManager.class),
2506 new Injector.SystemServiceProducer<>(AppOpsManager.class),
2507 (i, pm) -> AppsFilter.create(pm.mPmInternal, i),
2508 (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"));
2510 PackageManagerService m = new PackageManagerService(injector, factoryTest, onlyCore);
2511 t.traceEnd(); // "create package manager"
2513 injector.getCompatibility().registerListener(SELinuxMMAC.SELINUX_LATEST_CHANGES,
2515 synchronized (m.mInstallLock) {
2516 final AndroidPackage pkg;
2517 final PackageSetting ps;
2518 final SharedUserSetting sharedUser;
2519 final String oldSeInfo;
2520 synchronized (m.mLock) {
2521 ps = m.mSettings.getPackageLPr(packageName);
2523 Slog.e(TAG, "Failed to find package setting " + packageName);
2527 sharedUser = ps.getSharedUser();
2528 oldSeInfo = AndroidPackageUtils.getSeInfo(pkg, ps);
2532 Slog.e(TAG, "Failed to find package " + packageName);
2535 final String newSeInfo = SELinuxMMAC.getSeInfo(pkg, sharedUser,
2536 m.mInjector.getCompatibility());
2538 if (!newSeInfo.equals(oldSeInfo)) {
2539 Slog.i(TAG, "Updating seInfo for package " + packageName + " from: "
2540 + oldSeInfo + " to: " + newSeInfo);
2541 ps.getPkgState().setOverrideSeInfo(newSeInfo);
2542 m.prepareAppDataAfterInstallLIF(pkg);
2547 m.installWhitelistedSystemPackages();
2548 ServiceManager.addService("package", m);
2549 final PackageManagerNative pmn = m.new PackageManagerNative();
2550 ServiceManager.addService("package_native", pmn);
2554 /** Install/uninstall system packages for all users based on their user-type, as applicable. */
2555 private void installWhitelistedSystemPackages() {
2556 synchronized (mLock) {
2557 final boolean scheduleWrite = mUserManager.installWhitelistedSystemPackages(
2558 isFirstBoot(), isDeviceUpgrading());
2559 if (scheduleWrite) {
2560 scheduleWritePackageRestrictionsLocked(UserHandle.USER_ALL);
2565 private static void getDefaultDisplayMetrics(
2566 DisplayManager displayManager, DisplayMetrics metrics) {
2567 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2571 * Requests that files preopted on a secondary system partition be copied to the data partition
2572 * if possible. Note that the actual copying of the files is accomplished by init for security
2573 * reasons. This simply requests that the copy takes place and awaits confirmation of its
2574 * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2576 private static void requestCopyPreoptedFiles() {
2577 final int WAIT_TIME_MS = 100;
2578 final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2579 if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2580 SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2581 // We will wait for up to 100 seconds.
2582 final long timeStart = SystemClock.uptimeMillis();
2583 final long timeEnd = timeStart + 100 * 1000;
2584 long timeNow = timeStart;
2585 while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2587 Thread.sleep(WAIT_TIME_MS);
2588 } catch (InterruptedException e) {
2591 timeNow = SystemClock.uptimeMillis();
2592 if (timeNow > timeEnd) {
2593 SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2594 Slog.wtf(TAG, "cppreopt did not finish!");
2599 Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2604 public static class ScanPartition extends SystemPartition {
2606 public final int scanFlag;
2608 public ScanPartition(@NonNull SystemPartition partition) {
2610 scanFlag = scanFlagForPartition(partition);
2614 * Creates a partition containing the same folders as the original partition but with a
2615 * different root folder. The new partition will include the scan flags of the original
2616 * partition along with any specified additional scan flags.
2618 public ScanPartition(@NonNull File folder, @NonNull ScanPartition original,
2619 @ScanFlags int additionalScanFlag) {
2620 super(folder, original);
2621 this.scanFlag = original.scanFlag | additionalScanFlag;
2624 private static int scanFlagForPartition(PackagePartitions.SystemPartition partition) {
2625 switch (partition.type) {
2626 case PackagePartitions.PARTITION_SYSTEM:
2628 case PackagePartitions.PARTITION_VENDOR:
2629 return SCAN_AS_VENDOR;
2630 case PackagePartitions.PARTITION_ODM:
2632 case PackagePartitions.PARTITION_OEM:
2634 case PackagePartitions.PARTITION_PRODUCT:
2635 return SCAN_AS_PRODUCT;
2636 case PackagePartitions.PARTITION_SYSTEM_EXT:
2637 return SCAN_AS_SYSTEM_EXT;
2639 throw new IllegalStateException("Unable to determine scan flag for "
2640 + partition.folder);
2645 public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) {
2646 PackageManager.invalidatePackageInfoCache();
2647 PackageManager.disableApplicationInfoCache();
2648 PackageManager.disablePackageInfoCache();
2650 final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
2651 Trace.TRACE_TAG_PACKAGE_MANAGER);
2652 mInjector = injector;
2653 mInjector.bootstrap(this);
2654 mLock = injector.getLock();
2655 mInstallLock = injector.getInstallLock();
2656 LockGuard.installLock(mLock, LockGuard.INDEX_PACKAGES);
2657 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2658 SystemClock.uptimeMillis());
2660 if (mSdkVersion <= 0) {
2661 Slog.w(TAG, "**** ro.build.version.sdk not set!");
2664 mContext = injector.getContext();
2665 mFactoryTest = factoryTest;
2666 mOnlyCore = onlyCore;
2667 mMetrics = new DisplayMetrics();
2668 mInstaller = injector.getInstaller();
2670 // Create sub-components that provide services / data. Order here is important.
2671 t.traceBegin("createSubComponents");
2673 // Expose private service for system components to use.
2674 mPmInternal = new PackageManagerInternalImpl();
2675 LocalServices.addService(PackageManagerInternal.class, mPmInternal);
2676 mUserManager = injector.getUserManagerService();
2677 mComponentResolver = injector.getComponentResolver();
2678 mPermissionManager = injector.getPermissionManagerServiceInternal();
2679 mSettings = injector.getSettings();
2680 mPermissionManagerService = (IPermissionManager) ServiceManager.getService("permissionmgr");
2681 mIncrementalManager =
2682 (IncrementalManager) mContext.getSystemService(Context.INCREMENTAL_SERVICE);
2684 // CHECKSTYLE:ON IndentationCheck
2687 t.traceBegin("addSharedUsers");
2688 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2689 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2690 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2691 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2692 mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2693 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2694 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2695 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2696 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2697 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2698 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2699 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2700 mSettings.addSharedUserLPw("android.uid.se", SE_UID,
2701 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2702 mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID,
2703 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2706 String separateProcesses = SystemProperties.get("debug.separate_processes");
2707 if (separateProcesses != null && separateProcesses.length() > 0) {
2708 if ("*".equals(separateProcesses)) {
2709 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2710 mSeparateProcesses = null;
2711 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2714 mSeparateProcesses = separateProcesses.split(",");
2715 Slog.w(TAG, "Running with debug.separate_processes: "
2716 + separateProcesses);
2720 mSeparateProcesses = null;
2723 mPackageDexOptimizer = new PackageDexOptimizer(mInstaller, mInstallLock, mContext,
2726 new DexManager(mContext, this, mPackageDexOptimizer, mInstaller, mInstallLock);
2727 mArtManagerService = new ArtManagerService(mContext, this, mInstaller, mInstallLock);
2728 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2730 mViewCompiler = new ViewCompiler(mInstallLock, mInstaller);
2732 getDefaultDisplayMetrics(mInjector.getDisplayManager(), mMetrics);
2734 t.traceBegin("get system config");
2735 SystemConfig systemConfig = SystemConfig.getInstance();
2736 mAvailableFeatures = systemConfig.getAvailableFeatures();
2737 ApplicationPackageManager.invalidateHasSystemFeatureCache();
2740 mProtectedPackages = new ProtectedPackages(mContext);
2742 mApexManager = ApexManager.getInstance();
2743 mAppsFilter = mInjector.getAppsFilter();
2745 mDirsToScanAsSystem = new ArrayList<>();
2746 mDirsToScanAsSystem.addAll(SYSTEM_PARTITIONS);
2747 mDirsToScanAsSystem.addAll(mApexManager.getActiveApexInfos().stream()
2748 .map(PackageManagerService::resolveApexToScanPartition)
2749 .filter(Objects::nonNull).collect(Collectors.toList()));
2751 "Directories scanned as system partitions: [" + mDirsToScanAsSystem.stream().map(
2752 d -> (d.folder.getAbsolutePath() + ":" + d.scanFlag))
2753 .collect(Collectors.joining(",")) + "]");
2755 // CHECKSTYLE:OFF IndentationCheck
2756 synchronized (mInstallLock) {
2758 synchronized (mLock) {
2759 mHandlerThread = new ServiceThread(TAG,
2760 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2761 mHandlerThread.start();
2762 mHandler = new PackageHandler(mHandlerThread.getLooper());
2763 mProcessLoggingHandler = new ProcessLoggingHandler();
2764 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2765 mInstantAppRegistry = new InstantAppRegistry(this);
2767 ArrayMap<String, SystemConfig.SharedLibraryEntry> libConfig
2768 = systemConfig.getSharedLibraries();
2769 final int builtInLibCount = libConfig.size();
2770 for (int i = 0; i < builtInLibCount; i++) {
2771 String name = libConfig.keyAt(i);
2772 SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
2773 addBuiltInSharedLibraryLocked(entry.filename, name);
2776 // Now that we have added all the libraries, iterate again to add dependency
2777 // information IFF their dependencies are added.
2778 long undefinedVersion = SharedLibraryInfo.VERSION_UNDEFINED;
2779 for (int i = 0; i < builtInLibCount; i++) {
2780 String name = libConfig.keyAt(i);
2781 SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
2782 final int dependencyCount = entry.dependencies.length;
2783 for (int j = 0; j < dependencyCount; j++) {
2784 final SharedLibraryInfo dependency =
2785 getSharedLibraryInfoLPr(entry.dependencies[j], undefinedVersion);
2786 if (dependency != null) {
2787 getSharedLibraryInfoLPr(name, undefinedVersion).addDependency(dependency);
2792 SELinuxMMAC.readInstallPolicy();
2794 t.traceBegin("loadFallbacks");
2795 FallbackCategoryProvider.loadFallbacks();
2798 t.traceBegin("read user settings");
2799 mFirstBoot = !mSettings.readLPw(mUserManager.getUsers(false));
2802 // Clean up orphaned packages for which the code path doesn't exist
2803 // and they are an update to a system app - caused by bug/32321269
2804 final int packageSettingCount = mSettings.mPackages.size();
2805 for (int i = packageSettingCount - 1; i >= 0; i--) {
2806 PackageSetting ps = mSettings.mPackages.valueAt(i);
2807 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2808 && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2809 mSettings.mPackages.removeAt(i);
2810 mSettings.enableSystemPackageLPw(ps.name);
2814 if (!mOnlyCore && mFirstBoot) {
2815 requestCopyPreoptedFiles();
2818 String customResolverActivityName = Resources.getSystem().getString(
2819 R.string.config_customResolverActivity);
2820 if (!TextUtils.isEmpty(customResolverActivityName)) {
2821 mCustomResolverComponentName = ComponentName.unflattenFromString(
2822 customResolverActivityName);
2825 long startTime = SystemClock.uptimeMillis();
2827 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2830 final String bootClassPath = System.getenv("BOOTCLASSPATH");
2831 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2833 if (bootClassPath == null) {
2834 Slog.w(TAG, "No BOOTCLASSPATH found!");
2837 if (systemServerClassPath == null) {
2838 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2841 File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2843 final VersionInfo ver = mSettings.getInternalVersion();
2844 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2846 logCriticalInfo(Log.INFO,
2847 "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2850 // when upgrading from pre-M, promote system app permissions from install to runtime
2851 mPromoteSystemApps =
2852 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2854 // When upgrading from pre-N, we need to handle package extraction like first boot,
2855 // as there is no profiling data available.
2856 mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2858 mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2859 mIsPreQUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.Q;
2861 // save off the names of pre-existing system packages prior to scanning; we don't
2862 // want to automatically grant runtime permissions for new system apps
2863 if (mPromoteSystemApps) {
2864 for (PackageSetting ps : mSettings.mPackages.values()) {
2865 if (isSystemApp(ps)) {
2866 mExistingSystemPackages.add(ps.name);
2871 mCacheDir = preparePackageParserCache();
2873 // Set flag to monitor and not change apk file paths when
2874 // scanning install directories.
2875 int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2877 if (mIsUpgrade || mFirstBoot) {
2878 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2881 final int systemParseFlags = mDefParseFlags | PackageParser.PARSE_IS_SYSTEM_DIR;
2882 final int systemScanFlags = scanFlags | SCAN_AS_SYSTEM;
2884 PackageParser2 packageParser = new PackageParser2(mSeparateProcesses, mOnlyCore,
2885 mMetrics, mCacheDir, mPackageParserCallback);
2887 ExecutorService executorService = ParallelPackageParser.makeExecutorService();
2888 // Collect vendor/product/system_ext overlay packages. (Do this before scanning
2890 // For security and version matching reason, only consider overlay packages if they
2891 // reside in the right directory.
2892 for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
2893 final ScanPartition partition = mDirsToScanAsSystem.get(i);
2894 if (partition.getOverlayFolder() == null) {
2897 scanDirTracedLI(partition.getOverlayFolder(), systemParseFlags,
2898 systemScanFlags | partition.scanFlag, 0,
2899 packageParser, executorService);
2902 scanDirTracedLI(frameworkDir, systemParseFlags,
2903 systemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED, 0,
2904 packageParser, executorService);
2905 if (!mPackages.containsKey("android")) {
2906 throw new IllegalStateException(
2907 "Failed to load frameworks package; check log for warnings");
2909 for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
2910 final ScanPartition partition = mDirsToScanAsSystem.get(i);
2911 if (partition.getPrivAppFolder() != null) {
2912 scanDirTracedLI(partition.getPrivAppFolder(), systemParseFlags,
2913 systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0,
2914 packageParser, executorService);
2916 scanDirTracedLI(partition.getAppFolder(), systemParseFlags,
2917 systemScanFlags | partition.scanFlag, 0,
2918 packageParser, executorService);
2921 // Parse overlay configuration files to set default enable state, mutability, and
2922 // priority of system overlays.
2923 mOverlayConfig = OverlayConfig.initializeSystemInstance(
2924 consumer -> mPmInternal.forEachPackage(
2925 pkg -> consumer.accept(pkg, pkg.isSystem())));
2927 // Prune any system packages that no longer exist.
2928 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2929 // Stub packages must either be replaced with full versions in the /data
2930 // partition or be disabled.
2931 final List<String> stubSystemApps = new ArrayList<>();
2933 // do this first before mucking with mPackages for the "expecting better" case
2934 final Iterator<AndroidPackage> pkgIterator = mPackages.values().iterator();
2935 while (pkgIterator.hasNext()) {
2936 final AndroidPackage pkg = pkgIterator.next();
2938 stubSystemApps.add(pkg.getPackageName());
2942 final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2943 while (psit.hasNext()) {
2944 PackageSetting ps = psit.next();
2947 * If this is not a system app, it can't be a
2948 * disable system app.
2950 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2955 * If the package is scanned, it's not erased.
2957 final AndroidPackage scannedPkg = mPackages.get(ps.name);
2958 if (scannedPkg != null) {
2960 * If the system app is both scanned and in the
2961 * disabled packages list, then it must have been
2962 * added via OTA. Remove it from the currently
2963 * scanned package so the previously user-installed
2964 * application can be scanned.
2966 if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2967 logCriticalInfo(Log.WARN,
2968 "Expecting better updated system app for " + ps.name
2969 + "; removing system app. Last known"
2970 + " codePath=" + ps.codePathString
2971 + ", versionCode=" + ps.versionCode
2972 + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
2973 removePackageLI(scannedPkg, true);
2974 mExpectingBetter.put(ps.name, ps.codePath);
2980 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2982 logCriticalInfo(Log.WARN, "System package " + ps.name
2983 + " no longer exists; it's data will be wiped");
2984 // Actual deletion of code and data will be handled by later
2985 // reconciliation step
2987 // we still have a disabled system package, but, it still might have
2988 // been removed. check the code path still exists and check there's
2989 // still a package. the latter can happen if an OTA keeps the same
2990 // code path, but, changes the package name.
2991 final PackageSetting disabledPs =
2992 mSettings.getDisabledSystemPkgLPr(ps.name);
2993 if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2994 || disabledPs.pkg == null) {
2995 possiblyDeletedUpdatedSystemApps.add(ps.name);
2997 // We're expecting that the system app should remain disabled, but add
2998 // it to expecting better to recover in case the data version cannot
3000 mExpectingBetter.put(disabledPs.name, disabledPs.codePath);
3006 final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
3008 // Remove any shared userIDs that have no associated packages
3009 mSettings.pruneSharedUsersLPw();
3010 final long systemScanTime = SystemClock.uptimeMillis() - startTime;
3011 final int systemPackagesCount = mPackages.size();
3012 Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
3013 + " ms, packageCount: " + systemPackagesCount
3014 + " , timePerPackage: "
3015 + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
3016 + " , cached: " + cachedSystemApps);
3017 if (mIsUpgrade && systemPackagesCount > 0) {
3018 //CHECKSTYLE:OFF IndentationCheck
3019 FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
3020 BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME,
3021 systemScanTime / systemPackagesCount);
3022 //CHECKSTYLE:ON IndentationCheck
3025 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
3026 SystemClock.uptimeMillis());
3027 scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0,
3028 packageParser, executorService);
3032 List<Runnable> unfinishedTasks = executorService.shutdownNow();
3033 if (!unfinishedTasks.isEmpty()) {
3034 throw new IllegalStateException("Not all tasks finished before calling close: "
3039 // Remove disable package settings for updated system apps that were
3040 // removed via an OTA. If the update is no longer present, remove the
3041 // app completely. Otherwise, revoke their system privileges.
3042 for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
3043 final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
3044 final AndroidPackage pkg = mPackages.get(packageName);
3047 // remove from the disabled system list; do this first so any future
3048 // scans of this package are performed without this state
3049 mSettings.removeDisabledSystemPackageLPw(packageName);
3052 // should have found an update, but, we didn't; remove everything
3053 msg = "Updated system package " + packageName
3054 + " no longer exists; removing its data";
3055 // Actual deletion of code and data will be handled by later
3056 // reconciliation step
3058 // found an update; revoke system privileges
3059 msg = "Updated system package " + packageName
3060 + " no longer exists; rescanning package on data";
3062 // NOTE: We don't do anything special if a stub is removed from the
3063 // system image. But, if we were [like removing the uncompressed
3064 // version from the /data partition], this is where it'd be done.
3066 // remove the package from the system and re-scan it without any
3067 // special privileges
3068 removePackageLI(pkg, true);
3070 final File codePath = new File(pkg.getCodePath());
3071 scanPackageTracedLI(codePath, 0, scanFlags, 0, null);
3072 } catch (PackageManagerException e) {
3073 Slog.e(TAG, "Failed to parse updated, ex-system package: "
3078 // one final check. if we still have a package setting [ie. it was
3079 // previously scanned and known to the system], but, we don't have
3080 // a package [ie. there was an error scanning it from the /data
3081 // partition], completely remove the package data.
3082 final PackageSetting ps = mSettings.mPackages.get(packageName);
3083 if (ps != null && mPackages.get(packageName) == null) {
3084 removePackageDataLIF(ps, null, null, 0, false);
3087 logCriticalInfo(Log.WARN, msg);
3091 * Make sure all system apps that we expected to appear on
3092 * the userdata partition actually showed up. If they never
3093 * appeared, crawl back and revive the system version.
3095 for (int i = 0; i < mExpectingBetter.size(); i++) {
3096 final String packageName = mExpectingBetter.keyAt(i);
3097 if (!mPackages.containsKey(packageName)) {
3098 final File scanFile = mExpectingBetter.valueAt(i);
3100 logCriticalInfo(Log.WARN, "Expected better " + packageName
3101 + " but never showed up; reverting to system");
3103 @ParseFlags int reparseFlags = 0;
3104 @ScanFlags int rescanFlags = 0;
3105 for (int i1 = 0, size = mDirsToScanAsSystem.size(); i1 < size; i1++) {
3106 final ScanPartition partition = mDirsToScanAsSystem.get(i1);
3107 if (partition.containsPrivApp(scanFile)) {
3108 reparseFlags = systemParseFlags;
3109 rescanFlags = systemScanFlags | SCAN_AS_PRIVILEGED
3110 | partition.scanFlag;
3113 if (partition.containsApp(scanFile)) {
3114 reparseFlags = systemParseFlags;
3115 rescanFlags = systemScanFlags | partition.scanFlag;
3119 if (rescanFlags == 0) {
3120 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
3123 mSettings.enableSystemPackageLPw(packageName);
3126 scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
3127 } catch (PackageManagerException e) {
3128 Slog.e(TAG, "Failed to parse original system package: "
3134 // Uncompress and install any stubbed system applications.
3135 // This must be done last to ensure all stubs are replaced or disabled.
3136 installSystemStubPackages(stubSystemApps, scanFlags);
3138 final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
3141 final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
3142 final int dataPackagesCount = mPackages.size() - systemPackagesCount;
3143 Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
3144 + " ms, packageCount: " + dataPackagesCount
3145 + " , timePerPackage: "
3146 + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
3147 + " , cached: " + cachedNonSystemApps);
3148 if (mIsUpgrade && dataPackagesCount > 0) {
3149 //CHECKSTYLE:OFF IndentationCheck
3150 FrameworkStatsLog.write(
3151 FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
3152 BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME,
3153 dataScanTime / dataPackagesCount);
3154 //CHECKSTYLE:OFF IndentationCheck
3157 mExpectingBetter.clear();
3159 // Resolve the storage manager.
3160 mStorageManagerPackage = getStorageManagerPackageName();
3162 // Resolve protected action filters. Only the setup wizard is allowed to
3163 // have a high priority filter for these actions.
3164 mSetupWizardPackage = getSetupWizardPackageNameImpl();
3165 mComponentResolver.fixProtectedFilterPriorities();
3167 mDefaultTextClassifierPackage = getDefaultTextClassifierPackageName();
3168 mSystemTextClassifierPackageName = getSystemTextClassifierPackageName();
3169 mWellbeingPackage = getWellbeingPackageName();
3170 mDocumenterPackage = getDocumenterPackageName();
3171 mConfiguratorPackage = getDeviceConfiguratorPackageName();
3172 mAppPredictionServicePackage = getAppPredictionServicePackageName();
3173 mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
3174 mTelephonyPackages = getTelephonyPackageNames();
3175 mRetailDemoPackage = getRetailDemoPackageName();
3177 // Now that we know all of the shared libraries, update all clients to have
3178 // the correct library paths.
3179 updateAllSharedLibrariesLocked(null, null, Collections.unmodifiableMap(mPackages));
3181 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
3182 // NOTE: We ignore potential failures here during a system scan (like
3183 // the rest of the commands above) because there's precious little we
3184 // can do about it. A settings error is reported, though.
3185 final List<String> changedAbiCodePath =
3186 applyAdjustedAbiToSharedUser(setting, null /*scannedPackage*/,
3187 mInjector.getAbiHelper().getAdjustedAbiForSharedUser(
3188 setting.packages, null /*scannedPackage*/));
3189 if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
3190 for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
3191 final String codePathString = changedAbiCodePath.get(i);
3193 mInstaller.rmdex(codePathString,
3194 getDexCodeInstructionSet(getPreferredInstructionSet()));
3195 } catch (InstallerException ignored) {
3199 // Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
3201 setting.fixSeInfoLocked();
3202 setting.updateProcesses();
3205 // Now that we know all the packages we are keeping,
3206 // read and update their last usage times.
3207 mPackageUsage.read(mSettings.mPackages);
3208 mCompilerStats.read();
3210 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
3211 SystemClock.uptimeMillis());
3212 Slog.i(TAG, "Time to scan packages: "
3213 + ((SystemClock.uptimeMillis()-startTime)/1000f)
3216 // If the platform SDK has changed since the last time we booted,
3217 // we need to re-grant app permission to catch any new ones that
3218 // appear. This is really a hack, and means that apps can in some
3219 // cases get permissions that the user didn't initially explicitly
3220 // allow... it would be nice to have some better way to handle
3222 final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
3224 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
3225 + mSdkVersion + "; regranting permissions for internal storage");
3227 mPermissionManager.updateAllPermissions(
3228 StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated);
3229 ver.sdkVersion = mSdkVersion;
3231 // If this is the first boot or an update from pre-M, and it is a normal
3232 // boot, then we need to initialize the default preferred apps across
3233 // all defined users.
3234 if (!mOnlyCore && (mPromoteSystemApps || mFirstBoot)) {
3235 for (UserInfo user : mUserManager.getUsers(true)) {
3236 mSettings.applyDefaultPreferredAppsLPw(user.id);
3237 primeDomainVerificationsLPw(user.id);
3241 // Prepare storage for system user really early during boot,
3242 // since core system apps like SettingsProvider and SystemUI
3243 // can't wait for user to start
3244 final int storageFlags;
3245 if (StorageManager.isFileEncryptedNativeOrEmulated()) {
3246 storageFlags = StorageManager.FLAG_STORAGE_DE;
3248 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
3250 List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
3251 UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
3252 true /* onlyCoreApps */);
3253 mPrepareAppDataFuture = SystemServerInitThreadPool.submit(() -> {
3254 TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
3255 Trace.TRACE_TAG_PACKAGE_MANAGER);
3256 traceLog.traceBegin("AppDataFixup");
3258 mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
3259 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
3260 } catch (InstallerException e) {
3261 Slog.w(TAG, "Trouble fixing GIDs", e);
3263 traceLog.traceEnd();
3265 traceLog.traceBegin("AppDataPrepare");
3266 if (deferPackages == null || deferPackages.isEmpty()) {
3270 for (String pkgName : deferPackages) {
3271 AndroidPackage pkg = null;
3272 synchronized (mLock) {
3273 PackageSetting ps = mSettings.getPackageLPr(pkgName);
3274 if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
3279 synchronized (mInstallLock) {
3280 prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
3281 true /* maybeMigrateAppData */);
3286 traceLog.traceEnd();
3287 Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
3288 }, "prepareAppData");
3290 // If this is first boot after an OTA, and a normal boot, then
3291 // we need to clear code cache directories.
3292 // Note that we do *not* clear the application profiles. These remain valid
3293 // across OTAs and are used to drive profile verification (post OTA) and
3294 // profile compilation (without waiting to collect a fresh set of profiles).
3295 if (mIsUpgrade && !mOnlyCore) {
3296 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
3297 for (int i = 0; i < mSettings.mPackages.size(); i++) {
3298 final PackageSetting ps = mSettings.mPackages.valueAt(i);
3299 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
3300 // No apps are running this early, so no need to freeze
3301 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
3302 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
3303 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY
3304 | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
3307 ver.fingerprint = Build.FINGERPRINT;
3310 // Grandfather existing (installed before Q) non-system apps to hide
3311 // their icons in launcher.
3312 if (!mOnlyCore && mIsPreQUpgrade) {
3313 Slog.i(TAG, "Whitelisting all existing apps to hide their icons");
3314 int size = mSettings.mPackages.size();
3315 for (int i = 0; i < size; i++) {
3316 final PackageSetting ps = mSettings.mPackages.valueAt(i);
3317 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
3320 ps.disableComponentLPw(PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME,
3321 UserHandle.USER_SYSTEM);
3325 // clear only after permissions and other defaults have been updated
3326 mExistingSystemPackages.clear();
3327 mPromoteSystemApps = false;
3329 // All the changes are done during package scanning.
3330 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
3332 // can downgrade to reader
3333 t.traceBegin("write settings");
3334 mSettings.writeLPr();
3336 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3337 SystemClock.uptimeMillis());
3340 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3341 mRequiredInstallerPackage = getRequiredInstallerLPr();
3342 mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3343 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3344 if (mIntentFilterVerifierComponent != null) {
3345 mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3346 mIntentFilterVerifierComponent);
3348 mIntentFilterVerifier = null;
3350 mServicesExtensionPackageName = getRequiredServicesExtensionPackageLPr();
3351 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3352 PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3353 SharedLibraryInfo.VERSION_UNDEFINED);
3355 mRequiredVerifierPackage = null;
3356 mRequiredInstallerPackage = null;
3357 mRequiredUninstallerPackage = null;
3358 mIntentFilterVerifierComponent = null;
3359 mIntentFilterVerifier = null;
3360 mServicesExtensionPackageName = null;
3361 mSharedSystemSharedLibraryPackageName = null;
3364 // PermissionController hosts default permission granting and role management, so it's a
3365 // critical part of the core system.
3366 mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr();
3368 // Initialize InstantAppRegistry's Instant App list for all users.
3369 final int[] userIds = UserManagerService.getInstance().getUserIds();
3370 for (AndroidPackage pkg : mPackages.values()) {
3371 if (pkg.isSystem()) {
3374 for (int userId : userIds) {
3375 final PackageSetting ps = getPackageSetting(pkg.getPackageName());
3376 if (ps == null || !ps.getInstantApp(userId) || !ps.getInstalled(userId)) {
3379 mInstantAppRegistry.addInstantAppLPw(userId, ps.appId);
3383 mInstallerService = new PackageInstallerService(mContext, this);
3384 final Pair<ComponentName, String> instantAppResolverComponent =
3385 getInstantAppResolverLPr();
3386 if (instantAppResolverComponent != null) {
3387 if (DEBUG_INSTANT) {
3388 Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3390 mInstantAppResolverConnection = new InstantAppResolverConnection(
3391 mContext, instantAppResolverComponent.first,
3392 instantAppResolverComponent.second);
3393 mInstantAppResolverSettingsComponent =
3394 getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3396 mInstantAppResolverConnection = null;
3397 mInstantAppResolverSettingsComponent = null;
3399 updateInstantAppInstallerLocked(null);
3401 // Read and update the usage of dex files.
3402 // Do this at the end of PM init so that all the packages have their
3403 // data directory reconciled.
3404 // At this point we know the code paths of the packages, so we can validate
3405 // the disk file and build the internal cache.
3406 // The usage file is expected to be small so loading and verifying it
3407 // should take a fairly small time compare to the other activities (e.g. package
3409 final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3410 for (int userId : userIds) {
3411 userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3413 mDexManager.load(userPackages);
3415 FrameworkStatsLog.write(
3416 FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
3417 BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_INIT_TIME,
3418 SystemClock.uptimeMillis() - startTime);
3420 } // synchronized (mLock)
3421 } // synchronized (mInstallLock)
3422 // CHECKSTYLE:ON IndentationCheck
3424 mModuleInfoProvider = new ModuleInfoProvider(mContext, this);
3426 // Now after opening every single application zip, make sure they
3427 // are all flushed. Not really needed, but keeps things nice and
3430 Runtime.getRuntime().gc();
3433 // The initial scanning above does many calls into installd while
3434 // holding the mPackages lock, but we're mostly interested in yelling
3435 // once we have a booted system.
3436 mInstaller.setWarnIfHeld(mLock);
3438 PackageParser.readConfigUseRoundIcon(mContext.getResources());
3440 mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);
3444 * Uncompress and install stub applications.
3445 * <p>In order to save space on the system partition, some applications are shipped in a
3446 * compressed form. In addition the compressed bits for the full application, the
3447 * system image contains a tiny stub comprised of only the Android manifest.
3448 * <p>During the first boot, attempt to uncompress and install the full application. If
3449 * the application can't be installed for any reason, disable the stub and prevent
3450 * uncompressing the full application during future boots.
3451 * <p>In order to forcefully attempt an installation of a full application, go to app
3452 * settings and enable the application.
3454 private void installSystemStubPackages(@NonNull List<String> systemStubPackageNames,
3455 @ScanFlags int scanFlags) {
3456 for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) {
3457 final String packageName = systemStubPackageNames.get(i);
3458 // skip if the system package is already disabled
3459 if (mSettings.isDisabledSystemPackageLPr(packageName)) {
3460 systemStubPackageNames.remove(i);
3463 // skip if the package isn't installed (?!); this should never happen
3464 final AndroidPackage pkg = mPackages.get(packageName);
3466 systemStubPackageNames.remove(i);
3469 // skip if the package has been disabled by the user
3470 final PackageSetting ps = mSettings.mPackages.get(packageName);
3472 final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3473 if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3474 systemStubPackageNames.remove(i);
3479 // install the package to replace the stub on /system
3481 installStubPackageLI(pkg, 0, scanFlags);
3482 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3483 UserHandle.USER_SYSTEM, "android");
3484 systemStubPackageNames.remove(i);
3485 } catch (PackageManagerException e) {
3486 Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3489 // any failed attempt to install the package will be cleaned up later
3492 // disable any stub still left; these failed to install the full application
3493 for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) {
3494 final String pkgName = systemStubPackageNames.get(i);
3495 final PackageSetting ps = mSettings.mPackages.get(pkgName);
3496 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3497 UserHandle.USER_SYSTEM, "android");
3498 logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3503 * Extract, install and enable a stub package.
3504 * <p>If the compressed file can not be extracted / installed for any reason, the stub
3505 * APK will be installed and the package will be disabled. To recover from this situation,
3506 * the user will need to go into system settings and re-enable the package.
3508 private boolean enableCompressedPackage(AndroidPackage stubPkg,
3509 @NonNull PackageSetting stubPkgSetting) {
3510 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
3511 | PackageParser.PARSE_ENFORCE_CODE;
3512 synchronized (mInstallLock) {
3513 final AndroidPackage pkg;
3514 try (PackageFreezer freezer =
3515 freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
3516 pkg = installStubPackageLI(stubPkg, parseFlags, 0 /*scanFlags*/);
3517 synchronized (mLock) {
3518 prepareAppDataAfterInstallLIF(pkg);
3520 updateSharedLibrariesLocked(pkg, stubPkgSetting, null, null,
3521 Collections.unmodifiableMap(mPackages));
3522 } catch (PackageManagerException e) {
3523 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
3525 mPermissionManager.updatePermissions(pkg.getPackageName(), pkg);
3526 mSettings.writeLPr();
3528 } catch (PackageManagerException e) {
3529 // Whoops! Something went very wrong; roll back to the stub and disable the package
3530 try (PackageFreezer freezer =
3531 freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
3532 synchronized (mLock) {
3533 // NOTE: Ensure the system package is enabled; even for a compressed stub.
3534 // If we don't, installing the system package fails during scan
3535 enableSystemPackageLPw(stubPkg);
3537 installPackageFromSystemLIF(stubPkg.getCodePath(),
3538 null /*allUserHandles*/, null /*origUserHandles*/,
3539 null /*origPermissionsState*/, true /*writeSettings*/);
3540 } catch (PackageManagerException pme) {
3541 // Serious WTF; we have to be able to install the stub
3542 Slog.wtf(TAG, "Failed to restore system package:" + stubPkg.getPackageName(),
3545 // Disable the package; the stub by itself is not runnable
3546 synchronized (mLock) {
3547 final PackageSetting stubPs = mSettings.mPackages.get(
3548 stubPkg.getPackageName());
3549 if (stubPs != null) {
3550 stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED,
3551 UserHandle.USER_SYSTEM, "android");
3553 mSettings.writeLPr();
3558 clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
3559 | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3560 mDexManager.notifyPackageUpdated(pkg.getPackageName(),
3561 pkg.getBaseCodePath(), pkg.getSplitCodePaths());
3566 private AndroidPackage installStubPackageLI(AndroidPackage stubPkg,
3567 @ParseFlags int parseFlags, @ScanFlags int scanFlags)
3568 throws PackageManagerException {
3569 if (DEBUG_COMPRESSION) {
3570 Slog.i(TAG, "Uncompressing system stub; pkg: " + stubPkg.getPackageName());
3572 // uncompress the binary to its eventual destination on /data
3573 final File scanFile = decompressPackage(stubPkg.getPackageName(), stubPkg.getCodePath());
3574 if (scanFile == null) {
3575 throw new PackageManagerException(
3576 "Unable to decompress stub at " + stubPkg.getCodePath());
3578 synchronized (mLock) {
3579 mSettings.disableSystemPackageLPw(stubPkg.getPackageName(), true /*replaced*/);
3581 removePackageLI(stubPkg, true /*chatty*/);
3583 return scanPackageTracedLI(scanFile, parseFlags, scanFlags, 0, null);
3584 } catch (PackageManagerException e) {
3585 Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.getPackageName(),
3587 // Remove the failed install
3588 removeCodePathLI(scanFile);
3594 * Decompresses the given package on the system image onto
3595 * the /data partition.
3596 * @return The directory the package was decompressed into. Otherwise, {@code null}.
3598 private File decompressPackage(String packageName, String codePath) {
3599 final File[] compressedFiles = getCompressedFiles(codePath);
3600 if (compressedFiles == null || compressedFiles.length == 0) {
3601 if (DEBUG_COMPRESSION) {
3602 Slog.i(TAG, "No files to decompress: " + codePath);
3606 final File dstCodePath =
3607 getNextCodePath(Environment.getDataAppDirectory(null), packageName);
3608 int ret = PackageManager.INSTALL_SUCCEEDED;
3610 makeDirRecursive(dstCodePath, 0755);
3611 for (File srcFile : compressedFiles) {
3612 final String srcFileName = srcFile.getName();
3613 final String dstFileName = srcFileName.substring(
3614 0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3615 final File dstFile = new File(dstCodePath, dstFileName);
3616 ret = decompressFile(srcFile, dstFile);
3617 if (ret != PackageManager.INSTALL_SUCCEEDED) {
3618 logCriticalInfo(Log.ERROR, "Failed to decompress"
3619 + "; pkg: " + packageName
3620 + ", file: " + dstFileName);
3624 } catch (ErrnoException e) {
3625 logCriticalInfo(Log.ERROR, "Failed to decompress"
3626 + "; pkg: " + packageName
3627 + ", err: " + e.errno);
3629 if (ret == PackageManager.INSTALL_SUCCEEDED) {
3630 final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3631 NativeLibraryHelper.Handle handle = null;
3633 handle = NativeLibraryHelper.Handle.create(dstCodePath);
3634 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3635 null /*abiOverride*/, false /*isIncremental*/);
3636 } catch (IOException e) {
3637 logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3638 + "; pkg: " + packageName);
3639 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3641 IoUtils.closeQuietly(handle);
3644 if (ret != PackageManager.INSTALL_SUCCEEDED) {
3645 if (!dstCodePath.exists()) {
3648 removeCodePathLI(dstCodePath);
3656 private void updateInstantAppInstallerLocked(String modifiedPackage) {
3657 // we're only interested in updating the installer appliction when 1) it's not
3658 // already set or 2) the modified package is the installer
3659 if (mInstantAppInstallerActivity != null
3660 && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3661 .equals(modifiedPackage)) {
3664 setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3667 private static @Nullable File preparePackageParserCache() {
3668 if (!FORCE_PACKAGE_PARSED_CACHE_ENABLED) {
3669 if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3673 // Disable package parsing on eng builds to allow for faster incremental development.
3678 if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3679 Slog.i(TAG, "Disabling package parser cache due to system property.");
3684 // The base directory for the package parser cache lives under /data/system/.
3685 final File cacheBaseDir = Environment.getPackageCacheDirectory();
3686 if (!FileUtils.createDir(cacheBaseDir)) {
3690 // There are several items that need to be combined together to safely
3691 // identify cached items. In particular, changing the value of certain
3692 // feature flags should cause us to invalidate any caches.
3693 final String cacheName = FORCE_PACKAGE_PARSED_CACHE_ENABLED ? "debug"
3694 : SystemProperties.digestOf(
3695 "ro.build.fingerprint",
3696 StorageManager.PROP_ISOLATED_STORAGE,
3697 StorageManager.PROP_ISOLATED_STORAGE_SNAPSHOT
3700 // Reconcile cache directories, keeping only what we'd actually use.
3701 for (File cacheDir : FileUtils.listFilesOrEmpty(cacheBaseDir)) {
3702 if (Objects.equals(cacheName, cacheDir.getName())) {
3703 Slog.d(TAG, "Keeping known cache " + cacheDir.getName());
3705 Slog.d(TAG, "Destroying unknown cache " + cacheDir.getName());
3706 FileUtils.deleteContentsAndDir(cacheDir);
3710 // Return the versioned package cache directory.
3711 File cacheDir = FileUtils.createDir(cacheBaseDir, cacheName);
3713 if (cacheDir == null) {
3714 // Something went wrong. Attempt to delete everything and return.
3715 Slog.wtf(TAG, "Cache directory cannot be created - wiping base dir " + cacheBaseDir);
3716 FileUtils.deleteContentsAndDir(cacheBaseDir);
3720 // The following is a workaround to aid development on non-numbered userdebug
3721 // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3722 // the system partition is newer.
3724 // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3725 // that starts with "eng." to signify that this is an engineering build and not
3726 // destined for release.
3727 if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3728 Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3730 // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3731 // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3732 // in general and should not be used for production changes. In this specific case,
3733 // we know that they will work.
3734 File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3735 if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3736 FileUtils.deleteContents(cacheBaseDir);
3737 cacheDir = FileUtils.createDir(cacheBaseDir, cacheName);
3745 public boolean isFirstBoot() {
3746 // allow instant applications
3751 public boolean isOnlyCoreApps() {
3752 // allow instant applications
3757 public boolean isDeviceUpgrading() {
3758 // allow instant applications
3759 // The system property allows testing ota flow when upgraded to the same image.
3760 return mIsUpgrade || SystemProperties.getBoolean(
3761 "persist.pm.mock-upgrade", false /* default */);
3764 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3765 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3767 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3768 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3769 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3770 if (matches.size() == 1) {
3771 return matches.get(0).getComponentInfo().packageName;
3772 } else if (matches.size() == 0) {
3773 Log.e(TAG, "There should probably be a verifier, but, none were found");
3776 throw new RuntimeException("There must be exactly one verifier; found " + matches);
3779 private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3780 synchronized (mLock) {
3781 SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(name, version);
3782 if (libraryInfo == null) {
3783 throw new IllegalStateException("Missing required shared library:" + name);
3785 String packageName = libraryInfo.getPackageName();
3786 if (packageName == null) {
3787 throw new IllegalStateException("Expected a package for shared library " + name);
3794 private String getRequiredServicesExtensionPackageLPr() {
3795 String servicesExtensionPackage =
3796 ensureSystemPackageName(
3797 mContext.getString(R.string.config_servicesExtensionPackage));
3798 if (TextUtils.isEmpty(servicesExtensionPackage)) {
3799 throw new RuntimeException(
3800 "Required services extension package is missing, check "
3801 + "config_servicesExtensionPackage.");
3803 return servicesExtensionPackage;
3806 private @NonNull String getRequiredInstallerLPr() {
3807 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3808 intent.addCategory(Intent.CATEGORY_DEFAULT);
3809 intent.setDataAndType(Uri.parse("content://com.example/foo.apk"), PACKAGE_MIME_TYPE);
3811 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3812 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3813 UserHandle.USER_SYSTEM);
3814 if (matches.size() == 1) {
3815 ResolveInfo resolveInfo = matches.get(0);
3816 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3817 throw new RuntimeException("The installer must be a privileged app");
3819 return matches.get(0).getComponentInfo().packageName;
3821 throw new RuntimeException("There must be exactly one installer; found " + matches);
3825 private @NonNull String getRequiredUninstallerLPr() {
3826 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3827 intent.addCategory(Intent.CATEGORY_DEFAULT);
3828 intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3830 final ResolveInfo resolveInfo = resolveIntent(intent, null,
3831 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3832 UserHandle.USER_SYSTEM);
3833 if (resolveInfo == null ||
3834 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3835 throw new RuntimeException("There must be exactly one uninstaller; found "
3838 return resolveInfo.getComponentInfo().packageName;
3841 private @NonNull String getRequiredPermissionControllerLPr() {
3842 final Intent intent = new Intent(Intent.ACTION_MANAGE_PERMISSIONS);
3843 intent.addCategory(Intent.CATEGORY_DEFAULT);
3845 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
3846 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3847 UserHandle.USER_SYSTEM);
3848 if (matches.size() == 1) {
3849 ResolveInfo resolveInfo = matches.get(0);
3850 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3851 throw new RuntimeException("The permissions manager must be a privileged app");
3853 return matches.get(0).getComponentInfo().packageName;
3855 throw new RuntimeException("There must be exactly one permissions manager; found "
3860 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3861 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3863 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3864 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3865 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3866 ResolveInfo best = null;
3867 final int N = matches.size();
3868 for (int i = 0; i < N; i++) {
3869 final ResolveInfo cur = matches.get(i);
3870 final String packageName = cur.getComponentInfo().packageName;
3871 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3872 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3876 if (best == null || cur.priority > best.priority) {
3882 return best.getComponentInfo().getComponentName();
3884 Slog.w(TAG, "Intent filter verifier not found");
3889 public @Nullable ComponentName getInstantAppResolverComponent() {
3890 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3893 synchronized (mLock) {
3894 final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3895 if (instantAppResolver == null) {
3898 return instantAppResolver.first;
3902 private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3903 final String[] packageArray =
3904 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3905 if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3906 if (DEBUG_INSTANT) {
3907 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3912 final int callingUid = Binder.getCallingUid();
3913 final int resolveFlags =
3914 MATCH_DIRECT_BOOT_AWARE
3915 | MATCH_DIRECT_BOOT_UNAWARE
3916 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3917 String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3918 final Intent resolverIntent = new Intent(actionName);
3919 List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3920 resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3921 final int N = resolvers.size();
3923 if (DEBUG_INSTANT) {
3924 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3929 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3930 for (int i = 0; i < N; i++) {
3931 final ResolveInfo info = resolvers.get(i);
3933 if (info.serviceInfo == null) {
3937 final String packageName = info.serviceInfo.packageName;
3938 if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3939 if (DEBUG_INSTANT) {
3940 Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3941 + " pkg: " + packageName + ", info:" + info);
3946 if (DEBUG_INSTANT) {
3947 Slog.v(TAG, "Ephemeral resolver found;"
3948 + " pkg: " + packageName + ", info:" + info);
3950 return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3952 if (DEBUG_INSTANT) {
3953 Slog.v(TAG, "Ephemeral resolver NOT found");
3959 private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3960 String[] orderedActions = Build.IS_ENG
3962 Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE + "_TEST",
3963 Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE}
3965 Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE};
3967 final int resolveFlags =
3968 MATCH_DIRECT_BOOT_AWARE
3969 | MATCH_DIRECT_BOOT_UNAWARE
3970 | Intent.FLAG_IGNORE_EPHEMERAL
3971 | (!Build.IS_ENG ? MATCH_SYSTEM_ONLY : 0);
3972 final Intent intent = new Intent();
3973 intent.addCategory(Intent.CATEGORY_DEFAULT);
3974 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3975 List<ResolveInfo> matches = null;
3976 for (String action : orderedActions) {
3977 intent.setAction(action);
3978 matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3979 resolveFlags, UserHandle.USER_SYSTEM);
3980 if (matches.isEmpty()) {
3981 if (DEBUG_INSTANT) {
3982 Slog.d(TAG, "Instant App installer not found with " + action);
3988 Iterator<ResolveInfo> iter = matches.iterator();
3989 while (iter.hasNext()) {
3990 final ResolveInfo rInfo = iter.next();
3991 final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3993 final PermissionsState permissionsState = ps.getPermissionsState();
3994 if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)
4001 if (matches.size() == 0) {
4003 } else if (matches.size() == 1) {
4004 return (ActivityInfo) matches.get(0).getComponentInfo();
4006 throw new RuntimeException(
4007 "There must be at most one ephemeral installer; found " + matches);
4011 private @Nullable ComponentName getInstantAppResolverSettingsLPr(
4012 @NonNull ComponentName resolver) {
4013 final Intent intent = new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
4014 .addCategory(Intent.CATEGORY_DEFAULT)
4015 .setPackage(resolver.getPackageName());
4016 final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4017 List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
4018 UserHandle.USER_SYSTEM);
4019 if (matches.isEmpty()) {
4022 return matches.get(0).getComponentInfo().getComponentName();
4026 private void primeDomainVerificationsLPw(int userId) {
4027 if (DEBUG_DOMAIN_VERIFICATION) {
4028 Slog.d(TAG, "Priming domain verifications in user " + userId);
4031 SystemConfig systemConfig = SystemConfig.getInstance();
4032 ArraySet<String> packages = systemConfig.getLinkedApps();
4034 for (String packageName : packages) {
4035 AndroidPackage pkg = mPackages.get(packageName);
4037 if (!pkg.isSystem()) {
4038 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
4042 ArraySet<String> domains = null;
4043 for (ParsedActivity a : pkg.getActivities()) {
4044 for (ParsedIntentInfo filter : a.getIntents()) {
4045 if (hasValidDomains(filter)) {
4046 if (domains == null) {
4047 domains = new ArraySet<>();
4049 domains.addAll(filter.getHostsList());
4054 if (domains != null && domains.size() > 0) {
4055 if (DEBUG_DOMAIN_VERIFICATION) {
4056 Slog.v(TAG, " + " + packageName);
4058 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
4059 // state w.r.t. the formal app-linkage "no verification attempted" state;
4060 // and then 'always' in the per-user state actually used for intent resolution.
4061 final IntentFilterVerificationInfo ivi;
4062 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
4063 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
4064 mSettings.updateIntentFilterVerificationStatusLPw(packageName,
4065 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
4067 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
4068 + "' does not handle web links");
4071 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
4075 scheduleWritePackageRestrictionsLocked(userId);
4076 scheduleWriteSettingsLocked();
4079 private boolean packageIsBrowser(String packageName, int userId) {
4080 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
4081 PackageManager.MATCH_ALL, userId);
4082 final int N = list.size();
4083 for (int i = 0; i < N; i++) {
4084 ResolveInfo info = list.get(i);
4085 if (info.priority >= 0 && packageName.equals(info.activityInfo.packageName)) {
4093 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
4094 throws RemoteException {
4096 return super.onTransact(code, data, reply, flags);
4097 } catch (RuntimeException e) {
4098 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
4099 Slog.wtf(TAG, "Package Manager Crash", e);
4106 * Returns whether or not a full application can see an instant application.
4108 * Currently, there are four cases in which this can occur:
4110 * <li>The calling application is a "special" process. Special processes
4111 * are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
4112 * <li>The calling application has the permission
4113 * {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
4114 * <li>The calling application is the default launcher on the
4115 * system partition.</li>
4116 * <li>The calling application is the default app prediction service.</li>
4119 private boolean canViewInstantApps(int callingUid, int userId) {
4120 if (callingUid < Process.FIRST_APPLICATION_UID) {
4123 if (mContext.checkCallingOrSelfPermission(
4124 android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
4127 if (mContext.checkCallingOrSelfPermission(
4128 android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
4129 final ComponentName homeComponent = getDefaultHomeActivity(userId);
4130 if (homeComponent != null
4131 && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
4134 // TODO(b/122900055) Change/Remove this and replace with new permission role.
4135 if (mAppPredictionServicePackage != null
4136 && isCallerSameApp(mAppPredictionServicePackage, callingUid)) {
4143 private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
4144 if (!mUserManager.exists(userId)) return null;
4148 final int callingUid = Binder.getCallingUid();
4149 // Filter out ephemeral app metadata:
4150 // * The system/shell/root can see metadata for any app
4151 // * An installed app can see metadata for 1) other installed apps
4152 // and 2) ephemeral apps that have explicitly interacted with it
4153 // * Ephemeral apps can only see their own data and exposed installed apps
4154 // * Holding a signature permission allows seeing instant apps
4155 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
4159 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
4161 flags |= MATCH_ANY_USER;
4164 final PackageUserState state = ps.readUserState(userId);
4165 AndroidPackage p = ps.pkg;
4167 final PermissionsState permissionsState = ps.getPermissionsState();
4169 // Compute GIDs only if requested
4170 final int[] gids = (flags & PackageManager.GET_GIDS) == 0
4171 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
4172 // Compute granted permissions only if package has requested permissions
4173 final Set<String> permissions = ArrayUtils.isEmpty(p.getRequestedPermissions())
4174 ? Collections.emptySet() : permissionsState.getPermissions(userId);
4176 PackageInfo packageInfo = PackageInfoUtils.generate(p, gids, flags,
4177 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId, ps);
4179 if (packageInfo == null) {
4183 packageInfo.packageName = packageInfo.applicationInfo.packageName =
4184 resolveExternalPackageNameLPr(p);
4187 } else if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 && state.isAvailable(flags)) {
4188 PackageInfo pi = new PackageInfo();
4189 pi.packageName = ps.name;
4190 pi.setLongVersionCode(ps.versionCode);
4191 pi.sharedUserId = (ps.sharedUser != null) ? ps.sharedUser.name : null;
4192 pi.firstInstallTime = ps.firstInstallTime;
4193 pi.lastUpdateTime = ps.lastUpdateTime;
4195 ApplicationInfo ai = new ApplicationInfo();
4196 ai.packageName = ps.name;
4197 ai.uid = UserHandle.getUid(userId, ps.appId);
4198 ai.primaryCpuAbi = ps.primaryCpuAbiString;
4199 ai.secondaryCpuAbi = ps.secondaryCpuAbiString;
4200 ai.setVersionCode(ps.versionCode);
4201 ai.flags = ps.pkgFlags;
4202 ai.privateFlags = ps.pkgPrivateFlags;
4203 pi.applicationInfo = PackageParser.generateApplicationInfo(ai, flags, state, userId);
4205 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "ps.pkg is n/a for ["
4206 + ps.name + "]. Provides a minimum info.");
4214 public void checkPackageStartable(String packageName, int userId) {
4215 final int callingUid = Binder.getCallingUid();
4216 if (getInstantAppPackageName(callingUid) != null) {
4217 throw new SecurityException("Instant applications don't have access to this method");
4219 final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
4220 synchronized (mLock) {
4221 final PackageSetting ps = mSettings.mPackages.get(packageName);
4222 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
4223 throw new SecurityException("Package " + packageName + " was not found!");
4226 if (!ps.getInstalled(userId)) {
4227 throw new SecurityException(
4228 "Package " + packageName + " was not installed for user " + userId + "!");
4231 if (mSafeMode && !ps.isSystem()) {
4232 throw new SecurityException("Package " + packageName + " not a system app!");
4235 if (mFrozenPackages.contains(packageName)) {
4236 throw new SecurityException("Package " + packageName + " is currently frozen!");
4239 if (!userKeyUnlocked && !AndroidPackageUtils.isEncryptionAware(ps.pkg)) {
4240 throw new SecurityException("Package " + packageName + " is not encryption aware!");
4246 public boolean isPackageAvailable(String packageName, int userId) {
4247 if (!mUserManager.exists(userId)) return false;
4248 final int callingUid = Binder.getCallingUid();
4249 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4250 false /*requireFullPermission*/, false /*checkShell*/, "is package available");
4251 synchronized (mLock) {
4252 AndroidPackage p = mPackages.get(packageName);
4254 final PackageSetting ps = getPackageSetting(p.getPackageName());
4255 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
4259 final PackageUserState state = ps.readUserState(userId);
4260 if (state != null) {
4261 return PackageParser.isAvailable(state);
4270 public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
4271 return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
4272 flags, Binder.getCallingUid(), userId);
4276 public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
4277 int flags, int userId) {
4278 return getPackageInfoInternal(versionedPackage.getPackageName(),
4279 versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
4283 * Important: The provided filterCallingUid is used exclusively to filter out packages
4284 * that can be seen based on user state. It's typically the original caller uid prior
4285 * to clearing. Because it can only be provided by trusted code, it's value can be
4286 * trusted and will be used as-is; unlike userId which will be validated by this method.
4288 private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
4289 int flags, int filterCallingUid, int userId) {
4290 if (!mUserManager.exists(userId)) return null;
4291 flags = updateFlagsForPackage(flags, userId);
4292 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4293 false /* requireFullPermission */, false /* checkShell */, "get package info");
4296 synchronized (mLock) {
4297 // Normalize package name to handle renamed packages and static libs
4298 packageName = resolveInternalPackageNameLPr(packageName, versionCode);
4300 final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
4301 if (matchFactoryOnly) {
4302 // Instant app filtering for APEX modules is ignored
4303 if ((flags & MATCH_APEX) != 0) {
4304 return mApexManager.getPackageInfo(packageName,
4305 ApexManager.MATCH_FACTORY_PACKAGE);
4307 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
4309 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4312 if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
4315 return generatePackageInfo(ps, flags, userId);
4319 AndroidPackage p = mPackages.get(packageName);
4320 if (matchFactoryOnly && p != null && !p.isSystem()) {
4323 if (DEBUG_PACKAGE_INFO)
4324 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
4326 final PackageSetting ps = getPackageSetting(p.getPackageName());
4327 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4330 if (ps != null && shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
4334 return generatePackageInfo(ps, flags, userId);
4336 if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
4337 final PackageSetting ps = mSettings.mPackages.get(packageName);
4338 if (ps == null) return null;
4339 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4342 if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
4345 return generatePackageInfo(ps, flags, userId);
4347 if ((flags & MATCH_APEX) != 0) {
4348 return mApexManager.getPackageInfo(packageName, ApexManager.MATCH_ACTIVE_PACKAGE);
4354 private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
4355 if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
4358 if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
4361 if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
4367 private boolean isComponentVisibleToInstantApp(
4368 @Nullable ComponentName component, @ComponentType int type) {
4369 if (type == TYPE_ACTIVITY) {
4370 final ParsedActivity activity = mComponentResolver.getActivity(component);
4371 if (activity == null) {
4374 final boolean visibleToInstantApp =
4375 (activity.getFlags() & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4376 final boolean explicitlyVisibleToInstantApp =
4377 (activity.getFlags() & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
4378 return visibleToInstantApp && explicitlyVisibleToInstantApp;
4379 } else if (type == TYPE_RECEIVER) {
4380 final ParsedActivity activity = mComponentResolver.getReceiver(component);
4381 if (activity == null) {
4384 final boolean visibleToInstantApp =
4385 (activity.getFlags() & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4386 final boolean explicitlyVisibleToInstantApp =
4387 (activity.getFlags() & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
4388 return visibleToInstantApp && !explicitlyVisibleToInstantApp;
4389 } else if (type == TYPE_SERVICE) {
4390 final ParsedService service = mComponentResolver.getService(component);
4391 return service != null
4392 && (service.getFlags() & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4393 } else if (type == TYPE_PROVIDER) {
4394 final ParsedProvider provider = mComponentResolver.getProvider(component);
4395 return provider != null
4396 && (provider.getFlags() & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4397 } else if (type == TYPE_UNKNOWN) {
4398 return isComponentVisibleToInstantApp(component);
4404 * Returns whether or not access to the application should be filtered.
4406 * Access may be limited based upon whether the calling or target applications
4407 * are instant applications.
4409 * @see #canViewInstantApps(int, int)
4412 private boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid,
4413 @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4414 // if we're in an isolated process, get the real calling UID
4415 if (Process.isIsolated(callingUid)) {
4416 callingUid = mIsolatedOwners.get(callingUid);
4418 final String instantAppPkgName = getInstantAppPackageName(callingUid);
4419 final boolean callerIsInstantApp = instantAppPkgName != null;
4421 if (callerIsInstantApp) {
4422 // pretend the application exists, but, needs to be filtered
4427 // if the target and caller are the same application, don't filter
4428 if (isCallerSameApp(ps.name, callingUid)) {
4431 if (callerIsInstantApp) {
4432 // both caller and target are both instant, but, different applications, filter
4433 if (ps.getInstantApp(userId)) {
4436 // request for a specific component; if it hasn't been explicitly exposed through
4437 // property or instrumentation target, filter
4438 if (component != null) {
4439 final ParsedInstrumentation instrumentation =
4440 mInstrumentation.get(component);
4441 if (instrumentation != null
4442 && isCallerSameApp(instrumentation.getTargetPackage(), callingUid)) {
4445 return !isComponentVisibleToInstantApp(component, componentType);
4447 // request for application; if no components have been explicitly exposed, filter
4448 return !ps.pkg.isVisibleToInstantApps();
4450 if (ps.getInstantApp(userId)) {
4451 // caller can see all components of all instant applications, don't filter
4452 if (canViewInstantApps(callingUid, userId)) {
4455 // request for a specific instant application component, filter
4456 if (component != null) {
4459 // request for an instant application; if the caller hasn't been granted access, filter
4460 return !mInstantAppRegistry.isInstantAccessGranted(
4461 userId, UserHandle.getAppId(callingUid), ps.appId);
4463 int appId = UserHandle.getAppId(callingUid);
4464 final SettingBase callingPs = mSettings.getSettingLPr(appId);
4465 return mAppsFilter.shouldFilterApplication(callingUid, callingPs, ps, userId);
4469 * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
4472 private boolean shouldFilterApplicationLocked(
4473 @Nullable PackageSetting ps, int callingUid, int userId) {
4474 return shouldFilterApplicationLocked(ps, callingUid, null, TYPE_UNKNOWN, userId);
4478 private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4480 // Callers can access only the libs they depend on, otherwise they need to explicitly
4481 // ask for the shared libraries given the caller is allowed to access all static libs.
4482 if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4483 // System/shell/root get to see all static libs
4484 final int appId = UserHandle.getAppId(uid);
4485 if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4486 || appId == Process.ROOT_UID) {
4489 // Installer gets to see all static libs.
4490 if (PackageManager.PERMISSION_GRANTED
4491 == checkUidPermission(Manifest.permission.INSTALL_PACKAGES, uid)) {
4496 // No package means no static lib as it is always on internal storage
4497 if (ps == null || ps.pkg == null || !ps.pkg.isStaticSharedLibrary()) {
4501 final SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(
4502 ps.pkg.getStaticSharedLibName(), ps.pkg.getStaticSharedLibVersion());
4503 if (libraryInfo == null) {
4507 final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4508 final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4509 if (uidPackageNames == null) {
4513 for (String uidPackageName : uidPackageNames) {
4514 if (ps.name.equals(uidPackageName)) {
4517 PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4518 if (uidPs != null) {
4519 final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4520 libraryInfo.getName());
4524 if (uidPs.pkg.getUsesStaticLibrariesVersions()[index]
4525 == libraryInfo.getLongVersion()) {
4534 public String[] currentToCanonicalPackageNames(String[] names) {
4535 final int callingUid = Binder.getCallingUid();
4536 if (getInstantAppPackageName(callingUid) != null) {
4539 final String[] out = new String[names.length];
4541 synchronized (mLock) {
4542 final int callingUserId = UserHandle.getUserId(callingUid);
4543 final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4544 for (int i=names.length-1; i>=0; i--) {
4545 final PackageSetting ps = mSettings.mPackages.get(names[i]);
4546 boolean translateName = false;
4547 if (ps != null && ps.realName != null) {
4548 final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4549 translateName = !targetIsInstantApp
4550 || canViewInstantApps
4551 || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4552 UserHandle.getAppId(callingUid), ps.appId);
4554 out[i] = translateName ? ps.realName : names[i];
4561 public String[] canonicalToCurrentPackageNames(String[] names) {
4562 final int callingUid = Binder.getCallingUid();
4563 if (getInstantAppPackageName(callingUid) != null) {
4566 final String[] out = new String[names.length];
4568 synchronized (mLock) {
4569 final int callingUserId = UserHandle.getUserId(callingUid);
4570 final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4571 for (int i=names.length-1; i>=0; i--) {
4572 final String cur = mSettings.getRenamedPackageLPr(names[i]);
4573 boolean translateName = false;
4575 final PackageSetting ps = mSettings.mPackages.get(names[i]);
4576 final boolean targetIsInstantApp =
4577 ps != null && ps.getInstantApp(callingUserId);
4578 translateName = !targetIsInstantApp
4579 || canViewInstantApps
4580 || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4581 UserHandle.getAppId(callingUid), ps.appId);
4583 out[i] = translateName ? cur : names[i];
4590 public int getPackageUid(String packageName, int flags, int userId) {
4591 if (!mUserManager.exists(userId)) return -1;
4592 final int callingUid = Binder.getCallingUid();
4593 flags = updateFlagsForPackage(flags, userId);
4594 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4595 false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4596 return getPackageUidInternal(packageName, flags, userId, callingUid);
4599 private int getPackageUidInternal(String packageName, int flags, int userId, int callingUid) {
4601 synchronized (mLock) {
4602 final AndroidPackage p = mPackages.get(packageName);
4603 if (p != null && AndroidPackageUtils.isMatchForSystemOnly(p, flags)) {
4604 PackageSetting ps = getPackageSettingInternal(p.getPackageName(), callingUid);
4605 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
4608 return UserHandle.getUid(userId, p.getUid());
4610 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4611 final PackageSetting ps = mSettings.mPackages.get(packageName);
4612 if (ps != null && ps.isMatch(flags)
4613 && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
4614 return UserHandle.getUid(userId, ps.appId);
4623 public int[] getPackageGids(String packageName, int flags, int userId) {
4624 if (!mUserManager.exists(userId)) return null;
4625 final int callingUid = Binder.getCallingUid();
4626 flags = updateFlagsForPackage(flags, userId);
4627 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4628 false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4631 synchronized (mLock) {
4632 final AndroidPackage p = mPackages.get(packageName);
4633 if (p != null && AndroidPackageUtils.isMatchForSystemOnly(p, flags)) {
4634 PackageSetting ps = getPackageSetting(p.getPackageName());
4635 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
4638 // TODO: Shouldn't this be checking for package installed state for userId and
4640 return ps.getPermissionsState().computeGids(userId);
4642 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4643 final PackageSetting ps = mSettings.mPackages.get(packageName);
4644 if (ps != null && ps.isMatch(flags)
4645 && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
4646 return ps.getPermissionsState().computeGids(userId);
4654 // NOTE: Can't remove due to unsupported app usage
4656 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
4658 // Because this is accessed via the package manager service AIDL,
4659 // go through the permission manager service AIDL
4660 return mPermissionManagerService.getPermissionGroupInfo(groupName, flags);
4661 } catch (RemoteException ignore) { }
4666 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4667 int filterCallingUid, int userId) {
4668 if (!mUserManager.exists(userId)) return null;
4669 PackageSetting ps = mSettings.mPackages.get(packageName);
4671 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4674 if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
4677 if (ps.pkg == null) {
4678 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4679 if (pInfo != null) {
4680 return pInfo.applicationInfo;
4684 ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(ps.pkg, flags,
4685 ps.readUserState(userId), userId, ps);
4687 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4695 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4696 return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4700 * Important: The provided filterCallingUid is used exclusively to filter out applications
4701 * that can be seen based on user state. It's typically the original caller uid prior
4702 * to clearing. Because it can only be provided by trusted code, it's value can be
4703 * trusted and will be used as-is; unlike userId which will be validated by this method.
4705 private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4706 int filterCallingUid, int userId) {
4707 if (!mUserManager.exists(userId)) return null;
4708 flags = updateFlagsForApplication(flags, userId);
4710 if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
4711 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4712 false /* requireFullPermission */, false /* checkShell */,
4713 "get application info");
4717 synchronized (mLock) {
4718 // Normalize package name to handle renamed packages and static libs
4719 packageName = resolveInternalPackageNameLPr(packageName,
4720 PackageManager.VERSION_CODE_HIGHEST);
4722 AndroidPackage p = mPackages.get(packageName);
4723 if (DEBUG_PACKAGE_INFO) Log.v(
4724 TAG, "getApplicationInfo " + packageName
4727 PackageSetting ps = mSettings.mPackages.get(packageName);
4728 if (ps == null) return null;
4729 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4732 if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
4735 // Note: isEnabledLP() does not apply here - always return info
4736 ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(
4737 p, flags, ps.readUserState(userId), userId, ps);
4739 ai.packageName = resolveExternalPackageNameLPr(p);
4743 if ("android".equals(packageName)||"system".equals(packageName)) {
4744 return mAndroidApplication;
4746 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4747 // Already generates the external package name
4748 return generateApplicationInfoFromSettingsLPw(packageName,
4749 flags, filterCallingUid, userId);
4756 private String normalizePackageNameLPr(String packageName) {
4757 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4758 return normalizedPackageName != null ? normalizedPackageName : packageName;
4762 public void deletePreloadsFileCache() {
4763 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CLEAR_APP_CACHE,
4764 "deletePreloadsFileCache");
4765 File dir = Environment.getDataPreloadsFileCacheDirectory();
4766 Slog.i(TAG, "Deleting preloaded file cache " + dir);
4767 FileUtils.deleteContents(dir);
4771 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4772 final int storageFlags, final IPackageDataObserver observer) {
4773 mContext.enforceCallingOrSelfPermission(
4774 android.Manifest.permission.CLEAR_APP_CACHE, null);
4775 mHandler.post(() -> {
4776 boolean success = false;
4778 freeStorage(volumeUuid, freeStorageSize, storageFlags);
4780 } catch (IOException e) {
4783 if (observer != null) {
4785 observer.onRemoveCompleted(null, success);
4786 } catch (RemoteException e) {
4794 public void freeStorage(final String volumeUuid, final long freeStorageSize,
4795 final int storageFlags, final IntentSender pi) {
4796 mContext.enforceCallingOrSelfPermission(
4797 android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4798 mHandler.post(() -> {
4799 boolean success = false;
4801 freeStorage(volumeUuid, freeStorageSize, storageFlags);
4803 } catch (IOException e) {
4808 pi.sendIntent(null, success ? 1 : 0, null, null, null);
4809 } catch (SendIntentException e) {
4817 * Blocking call to clear various types of cached data across the system
4818 * until the requested bytes are available.
4820 public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4821 final StorageManager storage = mInjector.getStorageManager();
4822 final File file = storage.findPathForUuid(volumeUuid);
4823 if (file.getUsableSpace() >= bytes) return;
4825 if (ENABLE_FREE_CACHE_V2) {
4826 final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4828 final boolean aggressive = (storageFlags
4829 & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4830 final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4832 // 1. Pre-flight to determine if we have any chance to succeed
4833 // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4834 if (internalVolume && (aggressive || SystemProperties
4835 .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4836 deletePreloadsFileCache();
4837 if (file.getUsableSpace() >= bytes) return;
4840 // 3. Consider parsed APK data (aggressive only)
4841 if (internalVolume && aggressive) {
4842 FileUtils.deleteContents(mCacheDir);
4843 if (file.getUsableSpace() >= bytes) return;
4846 // 4. Consider cached app data (above quotas)
4848 mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4849 Installer.FLAG_FREE_CACHE_V2);
4850 } catch (InstallerException ignored) {
4852 if (file.getUsableSpace() >= bytes) return;
4854 // 5. Consider shared libraries with refcount=0 and age>min cache period
4855 if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4856 android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4857 Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4858 DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4862 // 6. Consider dexopt output (aggressive only)
4865 // 7. Consider installed instant apps unused longer than min cache period
4866 if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4867 android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4868 Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4869 InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4873 // 8. Consider cached app data (below quotas)
4875 mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4876 Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4877 } catch (InstallerException ignored) {
4879 if (file.getUsableSpace() >= bytes) return;
4881 // 9. Consider DropBox entries
4884 // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4885 if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4886 android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4887 Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4888 InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4893 mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4894 } catch (InstallerException ignored) {
4896 if (file.getUsableSpace() >= bytes) return;
4899 throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4902 private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4903 throws IOException {
4904 final StorageManager storage = mInjector.getStorageManager();
4905 final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4907 List<VersionedPackage> packagesToDelete = null;
4908 final long now = System.currentTimeMillis();
4910 synchronized (mLock) {
4911 final int[] allUsers = mUserManager.getUserIds();
4912 final int libCount = mSharedLibraries.size();
4913 for (int i = 0; i < libCount; i++) {
4914 final LongSparseArray<SharedLibraryInfo> versionedLib
4915 = mSharedLibraries.valueAt(i);
4916 if (versionedLib == null) {
4919 final int versionCount = versionedLib.size();
4920 for (int j = 0; j < versionCount; j++) {
4921 SharedLibraryInfo libInfo = versionedLib.valueAt(j);
4922 // Skip packages that are not static shared libs.
4923 if (!libInfo.isStatic()) {
4926 // Important: We skip static shared libs used for some user since
4927 // in such a case we need to keep the APK on the device. The check for
4928 // a lib being used for any user is performed by the uninstall call.
4929 final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4930 // Resolve the package name - we use synthetic package names internally
4931 final String internalPackageName = resolveInternalPackageNameLPr(
4932 declaringPackage.getPackageName(),
4933 declaringPackage.getLongVersionCode());
4934 final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4935 // Skip unused static shared libs cached less than the min period
4936 // to prevent pruning a lib needed by a subsequently installed package.
4937 if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4941 if (ps.pkg.isSystem()) {
4945 if (packagesToDelete == null) {
4946 packagesToDelete = new ArrayList<>();
4948 packagesToDelete.add(new VersionedPackage(internalPackageName,
4949 declaringPackage.getLongVersionCode()));
4954 if (packagesToDelete != null) {
4955 final int packageCount = packagesToDelete.size();
4956 for (int i = 0; i < packageCount; i++) {
4957 final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4958 // Delete the package synchronously (will fail of the lib used for any user).
4959 if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getLongVersionCode(),
4960 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4961 == PackageManager.DELETE_SUCCEEDED) {
4962 if (volume.getUsableSpace() >= neededSpace) {
4973 * Update given flags based on encryption status of current user.
4975 private int updateFlags(int flags, int userId) {
4976 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4977 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4978 // Caller expressed an explicit opinion about what encryption
4979 // aware/unaware components they want to see, so fall through and
4980 // give them what they want
4982 // Caller expressed no opinion, so match based on user state
4983 if (mUserManager.isUserUnlockingOrUnlocked(userId)) {
4984 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4986 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4993 * Update given flags when being used to request {@link PackageInfo}.
4995 private int updateFlagsForPackage(int flags, int userId) {
4996 final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4997 if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4998 // require the permission to be held; the calling uid and given user id referring
4999 // to the same user is not sufficient
5000 mPermissionManager.enforceCrossUserPermission(
5001 Binder.getCallingUid(), userId, false, false,
5002 !isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId),
5003 "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
5004 + Debug.getCallers(5));
5005 } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
5006 && mUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
5007 // If the caller wants all packages and has a restricted profile associated with it,
5008 // then match all users. This is to make sure that launchers that need to access work
5009 // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
5010 // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
5011 flags |= PackageManager.MATCH_ANY_USER;
5013 return updateFlags(flags, userId);
5017 * Update given flags when being used to request {@link ApplicationInfo}.
5019 private int updateFlagsForApplication(int flags, int userId) {
5020 return updateFlagsForPackage(flags, userId);
5024 * Update given flags when being used to request {@link ComponentInfo}.
5026 private int updateFlagsForComponent(int flags, int userId) {
5027 return updateFlags(flags, userId);
5031 * Update given intent when being used to request {@link ResolveInfo}.
5033 private Intent updateIntentForResolve(Intent intent) {
5034 if (intent.getSelector() != null) {
5035 intent = intent.getSelector();
5037 if (DEBUG_PREFERRED) {
5038 intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
5044 * Update given flags when being used to request {@link ResolveInfo}.
5045 * <p>Instant apps are resolved specially, depending upon context. Minimally,
5046 * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
5047 * flag set. However, this flag is only honoured in three circumstances:
5049 * <li>when called from a system process</li>
5050 * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
5051 * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
5052 * action and a {@code android.intent.category.BROWSABLE} category</li>
5055 int updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps) {
5056 return updateFlagsForResolve(flags, userId, callingUid,
5057 wantInstantApps, false /*onlyExposedExplicitly*/);
5060 int updateFlagsForResolve(int flags, int userId, int callingUid,
5061 boolean wantInstantApps, boolean onlyExposedExplicitly) {
5062 // Safe mode means we shouldn't match any third-party components
5064 flags |= PackageManager.MATCH_SYSTEM_ONLY;
5066 if (getInstantAppPackageName(callingUid) != null) {
5067 // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
5068 if (onlyExposedExplicitly) {
5069 flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
5071 flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
5072 flags |= PackageManager.MATCH_INSTANT;
5074 final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
5075 final boolean allowMatchInstant = wantInstantApps
5076 || (wantMatchInstant && canViewInstantApps(callingUid, userId));
5077 flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
5078 | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
5079 if (!allowMatchInstant) {
5080 flags &= ~PackageManager.MATCH_INSTANT;
5083 return updateFlagsForComponent(flags, userId);
5087 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
5088 return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
5092 * Important: The provided filterCallingUid is used exclusively to filter out activities
5093 * that can be seen based on user state. It's typically the original caller uid prior
5094 * to clearing. Because it can only be provided by trusted code, it's value can be
5095 * trusted and will be used as-is; unlike userId which will be validated by this method.
5097 private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
5098 int filterCallingUid, int userId) {
5099 if (!mUserManager.exists(userId)) return null;
5100 flags = updateFlagsForComponent(flags, userId);
5102 if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
5103 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
5104 false /* requireFullPermission */, false /* checkShell */, "get activity info");
5107 synchronized (mLock) {
5108 ParsedActivity a = mComponentResolver.getActivity(component);
5110 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
5112 AndroidPackage pkg = a == null ? null : mPackages.get(a.getPackageName());
5113 if (pkg != null && mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) {
5114 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5115 if (ps == null) return null;
5116 if (shouldFilterApplicationLocked(
5117 ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
5120 return PackageInfoUtils.generateActivityInfo(pkg,
5121 a, flags, ps.readUserState(userId), userId, ps);
5123 if (mResolveComponentName.equals(component)) {
5124 return PackageParser.generateActivityInfo(
5125 mResolveActivity, flags, new PackageUserState(), userId);
5131 private boolean isRecentsAccessingChildProfiles(int callingUid, int targetUserId) {
5132 if (!mInjector.getActivityTaskManagerInternal().isCallerRecents(callingUid)) {
5135 final long token = Binder.clearCallingIdentity();
5137 final int callingUserId = UserHandle.getUserId(callingUid);
5138 if (ActivityManager.getCurrentUser() != callingUserId) {
5141 return mUserManager.isSameProfileGroup(callingUserId, targetUserId);
5143 Binder.restoreCallingIdentity(token);
5148 public boolean activitySupportsIntent(ComponentName component, Intent intent,
5149 String resolvedType) {
5150 synchronized (mLock) {
5151 if (component.equals(mResolveComponentName)) {
5152 // The resolver supports EVERYTHING!
5155 final int callingUid = Binder.getCallingUid();
5156 final int callingUserId = UserHandle.getUserId(callingUid);
5157 ParsedActivity a = mComponentResolver.getActivity(component);
5161 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5165 if (shouldFilterApplicationLocked(
5166 ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
5169 for (int i=0; i< a.getIntents().size(); i++) {
5170 if (a.getIntents().get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
5171 intent.getData(), intent.getCategories(), TAG) >= 0) {
5180 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
5181 if (!mUserManager.exists(userId)) return null;
5182 final int callingUid = Binder.getCallingUid();
5183 flags = updateFlagsForComponent(flags, userId);
5184 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5185 false /* requireFullPermission */, false /* checkShell */, "get receiver info");
5186 synchronized (mLock) {
5187 ParsedActivity a = mComponentResolver.getReceiver(component);
5188 if (DEBUG_PACKAGE_INFO) Log.v(
5189 TAG, "getReceiverInfo " + component + ": " + a);
5195 AndroidPackage pkg = mPackages.get(a.getPackageName());
5200 if (mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) {
5201 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5202 if (ps == null) return null;
5203 if (shouldFilterApplicationLocked(
5204 ps, callingUid, component, TYPE_RECEIVER, userId)) {
5207 return PackageInfoUtils.generateActivityInfo(pkg,
5208 a, flags, ps.readUserState(userId), userId, ps);
5215 public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
5216 int flags, int userId) {
5217 if (!mUserManager.exists(userId)) return null;
5218 Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
5219 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5223 flags = updateFlagsForPackage(flags, userId);
5225 final boolean canSeeStaticLibraries =
5226 mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
5227 == PERMISSION_GRANTED
5228 || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
5229 == PERMISSION_GRANTED
5230 || canRequestPackageInstallsInternal(packageName,
5231 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
5232 false /* throwIfPermNotDeclared*/)
5233 || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
5234 == PERMISSION_GRANTED
5235 || mContext.checkCallingOrSelfPermission(
5236 Manifest.permission.ACCESS_SHARED_LIBRARIES) == PERMISSION_GRANTED;
5238 synchronized (mLock) {
5239 List<SharedLibraryInfo> result = null;
5241 final int libCount = mSharedLibraries.size();
5242 for (int i = 0; i < libCount; i++) {
5243 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.valueAt(i);
5244 if (versionedLib == null) {
5248 final int versionCount = versionedLib.size();
5249 for (int j = 0; j < versionCount; j++) {
5250 SharedLibraryInfo libInfo = versionedLib.valueAt(j);
5251 if (!canSeeStaticLibraries && libInfo.isStatic()) {
5254 final long identity = Binder.clearCallingIdentity();
5256 PackageInfo packageInfo = getPackageInfoVersioned(
5257 libInfo.getDeclaringPackage(), flags
5258 | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
5259 if (packageInfo == null) {
5263 Binder.restoreCallingIdentity(identity);
5266 SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getPath(),
5267 libInfo.getPackageName(), libInfo.getAllCodePaths(),
5268 libInfo.getName(), libInfo.getLongVersion(),
5269 libInfo.getType(), libInfo.getDeclaringPackage(),
5270 getPackagesUsingSharedLibraryLPr(libInfo, flags, userId),
5271 (libInfo.getDependencies() == null
5273 : new ArrayList<>(libInfo.getDependencies())));
5275 if (result == null) {
5276 result = new ArrayList<>();
5278 result.add(resLibInfo);
5282 return result != null ? new ParceledListSlice<>(result) : null;
5288 public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
5289 @NonNull String packageName, int flags, @NonNull int userId) {
5290 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_SHARED_LIBRARIES,
5291 "getDeclaredSharedLibraries");
5292 int callingUid = Binder.getCallingUid();
5293 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5294 true /* requireFullPermission */, false /* checkShell */,
5295 "getDeclaredSharedLibraries");
5297 Preconditions.checkNotNull(packageName, "packageName cannot be null");
5298 Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
5299 if (!mUserManager.exists(userId)) {
5303 if (getInstantAppPackageName(callingUid) != null) {
5307 synchronized (mLock) {
5308 List<SharedLibraryInfo> result = null;
5310 int libraryCount = mSharedLibraries.size();
5311 for (int i = 0; i < libraryCount; i++) {
5312 LongSparseArray<SharedLibraryInfo> versionedLibrary = mSharedLibraries.valueAt(i);
5313 if (versionedLibrary == null) {
5317 int versionCount = versionedLibrary.size();
5318 for (int j = 0; j < versionCount; j++) {
5319 SharedLibraryInfo libraryInfo = versionedLibrary.valueAt(j);
5321 VersionedPackage declaringPackage = libraryInfo.getDeclaringPackage();
5322 if (!Objects.equals(declaringPackage.getPackageName(), packageName)) {
5326 long identity = Binder.clearCallingIdentity();
5328 PackageInfo packageInfo = getPackageInfoVersioned(declaringPackage, flags
5329 | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
5330 if (packageInfo == null) {
5334 Binder.restoreCallingIdentity(identity);
5337 SharedLibraryInfo resultLibraryInfo = new SharedLibraryInfo(
5338 libraryInfo.getPath(), libraryInfo.getPackageName(),
5339 libraryInfo.getAllCodePaths(), libraryInfo.getName(),
5340 libraryInfo.getLongVersion(), libraryInfo.getType(),
5341 libraryInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(
5342 libraryInfo, flags, userId), libraryInfo.getDependencies() == null
5343 ? null : new ArrayList<>(libraryInfo.getDependencies()));
5345 if (result == null) {
5346 result = new ArrayList<>();
5348 result.add(resultLibraryInfo);
5352 return result != null ? new ParceledListSlice<>(result) : null;
5357 private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
5358 SharedLibraryInfo libInfo, int flags, int userId) {
5359 List<VersionedPackage> versionedPackages = null;
5360 final int packageCount = mSettings.mPackages.size();
5361 for (int i = 0; i < packageCount; i++) {
5362 PackageSetting ps = mSettings.mPackages.valueAt(i);
5368 if (!ps.readUserState(userId).isAvailable(flags)) {
5372 final String libName = libInfo.getName();
5373 if (libInfo.isStatic()) {
5374 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
5378 if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getLongVersion()) {
5381 if (versionedPackages == null) {
5382 versionedPackages = new ArrayList<>();
5384 // If the dependent is a static shared lib, use the public package name
5385 String dependentPackageName = ps.name;
5386 if (ps.pkg != null && ps.pkg.isStaticSharedLibrary()) {
5387 dependentPackageName = ps.pkg.getManifestPackageName();
5389 versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
5390 } else if (ps.pkg != null) {
5391 if (ArrayUtils.contains(ps.pkg.getUsesLibraries(), libName)
5392 || ArrayUtils.contains(ps.pkg.getUsesOptionalLibraries(), libName)) {
5393 if (versionedPackages == null) {
5394 versionedPackages = new ArrayList<>();
5396 versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
5401 return versionedPackages;
5405 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5406 if (!mUserManager.exists(userId)) return null;
5407 final int callingUid = Binder.getCallingUid();
5408 flags = updateFlagsForComponent(flags, userId);
5409 mPermissionManager.enforceCrossUserOrProfilePermission(
5410 callingUid, userId, false /* requireFullPermission */, false /* checkShell */,
5411 "get service info");
5412 synchronized (mLock) {
5413 ParsedService s = mComponentResolver.getService(component);
5414 if (DEBUG_PACKAGE_INFO) Log.v(
5415 TAG, "getServiceInfo " + component + ": " + s);
5420 AndroidPackage pkg = mPackages.get(s.getPackageName());
5421 if (mSettings.isEnabledAndMatchLPr(pkg, s, flags, userId)) {
5422 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5423 if (ps == null) return null;
5424 if (shouldFilterApplicationLocked(
5425 ps, callingUid, component, TYPE_SERVICE, userId)) {
5428 return PackageInfoUtils.generateServiceInfo(pkg,
5429 s, flags, ps.readUserState(userId), userId, ps);
5436 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
5437 if (!mUserManager.exists(userId)) return null;
5438 final int callingUid = Binder.getCallingUid();
5439 flags = updateFlagsForComponent(flags, userId);
5440 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5441 false /* requireFullPermission */, false /* checkShell */, "get provider info");
5442 synchronized (mLock) {
5443 ParsedProvider p = mComponentResolver.getProvider(component);
5444 if (DEBUG_PACKAGE_INFO) Log.v(
5445 TAG, "getProviderInfo " + component + ": " + p);
5450 AndroidPackage pkg = mPackages.get(p.getPackageName());
5455 if (mSettings.isEnabledAndMatchLPr(pkg, p, flags, userId)) {
5456 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5457 if (ps == null) return null;
5458 if (shouldFilterApplicationLocked(
5459 ps, callingUid, component, TYPE_PROVIDER, userId)) {
5462 PackageUserState state = ps.readUserState(userId);
5463 final ApplicationInfo appInfo = PackageInfoUtils.generateApplicationInfo(
5464 pkg, flags, state, userId, ps);
5465 if (appInfo == null) {
5468 return PackageInfoUtils.generateProviderInfo(
5469 pkg, p, flags, state, appInfo, userId, ps);
5476 public ModuleInfo getModuleInfo(String packageName, @ModuleInfoFlags int flags) {
5477 return mModuleInfoProvider.getModuleInfo(packageName, flags);
5481 public List<ModuleInfo> getInstalledModules(int flags) {
5482 return mModuleInfoProvider.getInstalledModules(flags);
5486 public String[] getSystemSharedLibraryNames() {
5487 // allow instant applications
5488 synchronized (mLock) {
5489 Set<String> libs = null;
5490 final int libCount = mSharedLibraries.size();
5491 for (int i = 0; i < libCount; i++) {
5492 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.valueAt(i);
5493 if (versionedLib == null) {
5496 final int versionCount = versionedLib.size();
5497 for (int j = 0; j < versionCount; j++) {
5498 SharedLibraryInfo libraryInfo = versionedLib.valueAt(j);
5499 if (!libraryInfo.isStatic()) {
5501 libs = new ArraySet<>();
5503 libs.add(libraryInfo.getName());
5506 PackageSetting ps = mSettings.getPackageLPr(libraryInfo.getPackageName());
5507 if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
5508 UserHandle.getUserId(Binder.getCallingUid()),
5509 PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
5511 libs = new ArraySet<>();
5513 libs.add(libraryInfo.getName());
5520 String[] libsArray = new String[libs.size()];
5521 libs.toArray(libsArray);
5530 public @NonNull String getServicesSystemSharedLibraryPackageName() {
5531 // allow instant applications
5532 synchronized (mLock) {
5533 return mServicesExtensionPackageName;
5538 public @NonNull String getSharedSystemSharedLibraryPackageName() {
5539 // allow instant applications
5540 synchronized (mLock) {
5541 return mSharedSystemSharedLibraryPackageName;
5546 private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5547 for (int i = userList.length - 1; i >= 0; --i) {
5548 final int userId = userList[i];
5549 // don't add instant app to the list of updates
5550 if (pkgSetting.getInstantApp(userId)) {
5553 SparseArray<String> changedPackages = mChangedPackages.get(userId);
5554 if (changedPackages == null) {
5555 changedPackages = new SparseArray<>();
5556 mChangedPackages.put(userId, changedPackages);
5558 Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5559 if (sequenceNumbers == null) {
5560 sequenceNumbers = new HashMap<>();
5561 mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5563 final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5564 if (sequenceNumber != null) {
5565 changedPackages.remove(sequenceNumber);
5567 changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5568 sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5570 mChangedPackagesSequenceNumber++;
5574 public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5575 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5578 synchronized (mLock) {
5579 if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5582 final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5583 if (changedPackages == null) {
5586 final List<String> packageNames =
5587 new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5588 for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5589 final String packageName = changedPackages.get(i);
5590 if (packageName != null) {
5591 packageNames.add(packageName);
5594 return packageNames.isEmpty()
5595 ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5600 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5601 // allow instant applications
5602 ArrayList<FeatureInfo> res;
5603 synchronized (mAvailableFeatures) {
5604 res = new ArrayList<>(mAvailableFeatures.size() + 1);
5605 res.addAll(mAvailableFeatures.values());
5607 final FeatureInfo fi = new FeatureInfo();
5608 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5609 FeatureInfo.GL_ES_VERSION_UNDEFINED);
5612 return new ParceledListSlice<>(res);
5616 public boolean hasSystemFeature(String name, int version) {
5617 // allow instant applications
5618 synchronized (mAvailableFeatures) {
5619 final FeatureInfo feat = mAvailableFeatures.get(name);
5623 return feat.version >= version;
5628 // NOTE: Can't remove due to unsupported app usage
5630 public int checkPermission(String permName, String pkgName, int userId) {
5632 // Because this is accessed via the package manager service AIDL,
5633 // go through the permission manager service AIDL
5634 return mPermissionManagerService.checkPermission(permName, pkgName, userId);
5635 } catch (RemoteException ignore) { }
5636 return PackageManager.PERMISSION_DENIED;
5639 // NOTE: Can't remove without a major refactor. Keep around for now.
5641 public int checkUidPermission(String permName, int uid) {
5643 // Because this is accessed via the package manager service AIDL,
5644 // go through the permission manager service AIDL
5645 return mPermissionManagerService.checkUidPermission(permName, uid);
5646 } catch (RemoteException ignore) { }
5647 return PackageManager.PERMISSION_DENIED;
5651 public String getPermissionControllerPackageName() {
5652 synchronized (mLock) {
5653 return mRequiredPermissionControllerPackage;
5657 String getPackageInstallerPackageName() {
5658 synchronized (mLock) {
5659 return mRequiredInstallerPackage;
5663 // NOTE: Can't remove due to unsupported app usage
5665 public boolean addPermission(PermissionInfo info) {
5667 // Because this is accessed via the package manager service AIDL,
5668 // go through the permission manager service AIDL
5669 return mPermissionManagerService.addPermission(info, false);
5670 } catch (RemoteException ignore) { }
5674 // NOTE: Can't remove due to unsupported app usage
5676 public boolean addPermissionAsync(PermissionInfo info) {
5678 // Because this is accessed via the package manager service AIDL,
5679 // go through the permission manager service AIDL
5680 return mPermissionManagerService.addPermission(info, true);
5681 } catch (RemoteException ignore) { }
5685 // NOTE: Can't remove due to unsupported app usage
5687 public void removePermission(String permName) {
5689 // Because this is accessed via the package manager service AIDL,
5690 // go through the permission manager service AIDL
5691 mPermissionManagerService.removePermission(permName);
5692 } catch (RemoteException ignore) { }
5695 // NOTE: Can't remove due to unsupported app usage
5697 public void grantRuntimePermission(String packageName, String permName, final int userId) {
5699 // Because this is accessed via the package manager service AIDL,
5700 // go through the permission manager service AIDL
5701 mPermissionManagerService.grantRuntimePermission(packageName, permName, userId);
5702 } catch (RemoteException ignore) { }
5706 public boolean isProtectedBroadcast(String actionName) {
5707 // allow instant applications
5708 synchronized (mProtectedBroadcasts) {
5709 if (mProtectedBroadcasts.contains(actionName)) {
5711 } else if (actionName != null) {
5712 // TODO: remove these terrible hacks
5713 if (actionName.startsWith("android.net.netmon.lingerExpired")
5714 || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5715 || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5716 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5725 public int checkSignatures(String pkg1, String pkg2) {
5726 synchronized (mLock) {
5727 final AndroidPackage p1 = mPackages.get(pkg1);
5728 final AndroidPackage p2 = mPackages.get(pkg2);
5729 final PackageSetting ps1 = p1 == null ? null : getPackageSetting(p1.getPackageName());
5730 final PackageSetting ps2 = p2 == null ? null : getPackageSetting(p2.getPackageName());
5731 if (p1 == null || ps1 == null || p2 == null || ps2 == null) {
5732 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5734 final int callingUid = Binder.getCallingUid();
5735 final int callingUserId = UserHandle.getUserId(callingUid);
5736 if (shouldFilterApplicationLocked(ps1, callingUid, callingUserId)
5737 || shouldFilterApplicationLocked(ps2, callingUid, callingUserId)) {
5738 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5740 return compareSignatures(p1.getSigningDetails().signatures,
5741 p2.getSigningDetails().signatures);
5746 public int checkUidSignatures(int uid1, int uid2) {
5747 final int callingUid = Binder.getCallingUid();
5748 final int callingUserId = UserHandle.getUserId(callingUid);
5749 final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5750 // Map to base uids.
5751 final int appId1 = UserHandle.getAppId(uid1);
5752 final int appId2 = UserHandle.getAppId(uid2);
5754 synchronized (mLock) {
5757 Object obj = mSettings.getSettingLPr(appId1);
5759 if (obj instanceof SharedUserSetting) {
5760 if (isCallerInstantApp) {
5761 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5763 s1 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
5764 } else if (obj instanceof PackageSetting) {
5765 final PackageSetting ps = (PackageSetting) obj;
5766 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
5767 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5769 s1 = ps.signatures.mSigningDetails.signatures;
5771 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5774 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5776 obj = mSettings.getSettingLPr(appId2);
5778 if (obj instanceof SharedUserSetting) {
5779 if (isCallerInstantApp) {
5780 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5782 s2 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
5783 } else if (obj instanceof PackageSetting) {
5784 final PackageSetting ps = (PackageSetting) obj;
5785 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
5786 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5788 s2 = ps.signatures.mSigningDetails.signatures;
5790 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5793 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5795 return compareSignatures(s1, s2);
5800 public boolean hasSigningCertificate(
5801 String packageName, byte[] certificate, @PackageManager.CertificateInputType int type) {
5803 synchronized (mLock) {
5804 final AndroidPackage p = mPackages.get(packageName);
5805 final PackageSetting ps = getPackageSetting(p.getPackageName());
5806 if (p == null || ps == null) {
5809 final int callingUid = Binder.getCallingUid();
5810 final int callingUserId = UserHandle.getUserId(callingUid);
5811 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
5815 case CERT_INPUT_RAW_X509:
5816 return p.getSigningDetails().hasCertificate(certificate);
5817 case CERT_INPUT_SHA256:
5818 return p.getSigningDetails().hasSha256Certificate(certificate);
5826 public boolean hasUidSigningCertificate(
5827 int uid, byte[] certificate, @PackageManager.CertificateInputType int type) {
5828 final int callingUid = Binder.getCallingUid();
5829 final int callingUserId = UserHandle.getUserId(callingUid);
5830 // Map to base uids.
5831 final int appId = UserHandle.getAppId(uid);
5833 synchronized (mLock) {
5834 final PackageParser.SigningDetails signingDetails;
5835 final Object obj = mSettings.getSettingLPr(appId);
5837 if (obj instanceof SharedUserSetting) {
5838 final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5839 if (isCallerInstantApp) {
5842 signingDetails = ((SharedUserSetting)obj).signatures.mSigningDetails;
5843 } else if (obj instanceof PackageSetting) {
5844 final PackageSetting ps = (PackageSetting) obj;
5845 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
5848 signingDetails = ps.signatures.mSigningDetails;
5856 case CERT_INPUT_RAW_X509:
5857 return signingDetails.hasCertificate(certificate);
5858 case CERT_INPUT_SHA256:
5859 return signingDetails.hasSha256Certificate(certificate);
5867 * If the database version for this type of package (internal storage or
5868 * external storage) is less than the version where package signatures
5869 * were updated, return true.
5871 private boolean isCompatSignatureUpdateNeeded(AndroidPackage pkg) {
5872 return isCompatSignatureUpdateNeeded(getSettingsVersionForPackage(pkg));
5875 private static boolean isCompatSignatureUpdateNeeded(VersionInfo ver) {
5876 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5879 private boolean isRecoverSignatureUpdateNeeded(AndroidPackage pkg) {
5880 return isRecoverSignatureUpdateNeeded(getSettingsVersionForPackage(pkg));
5883 private static boolean isRecoverSignatureUpdateNeeded(VersionInfo ver) {
5884 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5888 public List<String> getAllPackages() {
5889 final int callingUid = Binder.getCallingUid();
5890 final int callingUserId = UserHandle.getUserId(callingUid);
5891 synchronized (mLock) {
5892 if (canViewInstantApps(callingUid, callingUserId)) {
5893 return new ArrayList<>(mPackages.keySet());
5895 final String instantAppPkgName = getInstantAppPackageName(callingUid);
5896 final List<String> result = new ArrayList<>();
5897 if (instantAppPkgName != null) {
5898 // caller is an instant application; filter unexposed applications
5899 for (AndroidPackage pkg : mPackages.values()) {
5900 if (!pkg.isVisibleToInstantApps()) {
5903 result.add(pkg.getPackageName());
5906 // caller is a normal application; filter instant applications
5907 for (AndroidPackage pkg : mPackages.values()) {
5908 final PackageSetting ps = getPackageSetting(pkg.getPackageName());
5910 && ps.getInstantApp(callingUserId)
5911 && !mInstantAppRegistry.isInstantAccessGranted(
5912 callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
5915 result.add(pkg.getPackageName());
5923 * <em>IMPORTANT:</em> Not all packages returned by this method may be known
5924 * to the system. There are two conditions in which this may occur:
5926 * <li>The package is on adoptable storage and the device has been removed</li>
5927 * <li>The package is being removed and the internal structures are partially updated</li>
5929 * The second is an artifact of the current data structures and should be fixed. See
5930 * b/111075456 for one such instance.
5933 public String[] getPackagesForUid(int uid) {
5934 return getPackagesForUidInternal(uid, Binder.getCallingUid());
5937 private String[] getPackagesForUidInternal(int uid, int callingUid) {
5938 final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5939 final int userId = UserHandle.getUserId(uid);
5940 final int appId = UserHandle.getAppId(uid);
5942 synchronized (mLock) {
5943 final Object obj = mSettings.getSettingLPr(appId);
5944 if (obj instanceof SharedUserSetting) {
5945 if (isCallerInstantApp) {
5948 final SharedUserSetting sus = (SharedUserSetting) obj;
5949 final int N = sus.packages.size();
5950 String[] res = new String[N];
5951 final Iterator<PackageSetting> it = sus.packages.iterator();
5953 while (it.hasNext()) {
5954 PackageSetting ps = it.next();
5955 if (ps.getInstalled(userId)) {
5959 return ArrayUtils.trimToSize(res, i);
5960 } else if (obj instanceof PackageSetting) {
5961 final PackageSetting ps = (PackageSetting) obj;
5962 if (ps.getInstalled(userId)
5963 && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
5964 return new String[]{ps.name};
5972 public String getNameForUid(int uid) {
5973 final int callingUid = Binder.getCallingUid();
5974 if (getInstantAppPackageName(callingUid) != null) {
5977 final int appId = UserHandle.getAppId(uid);
5978 synchronized (mLock) {
5979 final Object obj = mSettings.getSettingLPr(appId);
5980 if (obj instanceof SharedUserSetting) {
5981 final SharedUserSetting sus = (SharedUserSetting) obj;
5982 return sus.name + ":" + sus.userId;
5983 } else if (obj instanceof PackageSetting) {
5984 final PackageSetting ps = (PackageSetting) obj;
5985 if (shouldFilterApplicationLocked(
5986 ps, callingUid, UserHandle.getUserId(callingUid))) {
5996 public String[] getNamesForUids(int[] uids) {
5997 if (uids == null || uids.length == 0) {
6000 final int callingUid = Binder.getCallingUid();
6001 if (getInstantAppPackageName(callingUid) != null) {
6004 final String[] names = new String[uids.length];
6005 synchronized (mLock) {
6006 for (int i = uids.length - 1; i >= 0; i--) {
6007 final int appId = UserHandle.getAppId(uids[i]);
6008 final Object obj = mSettings.getSettingLPr(appId);
6009 if (obj instanceof SharedUserSetting) {
6010 final SharedUserSetting sus = (SharedUserSetting) obj;
6011 names[i] = "shared:" + sus.name;
6012 } else if (obj instanceof PackageSetting) {
6013 final PackageSetting ps = (PackageSetting) obj;
6014 if (shouldFilterApplicationLocked(
6015 ps, callingUid, UserHandle.getUserId(callingUid))) {
6029 public int getUidForSharedUser(String sharedUserName) {
6030 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6033 if (sharedUserName == null) {
6037 synchronized (mLock) {
6038 SharedUserSetting suid;
6040 suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
6044 } catch (PackageManagerException ignore) {
6045 // can't happen, but, still need to catch it
6052 public int getFlagsForUid(int uid) {
6053 final int callingUid = Binder.getCallingUid();
6054 if (getInstantAppPackageName(callingUid) != null) {
6057 final int appId = UserHandle.getAppId(uid);
6058 synchronized (mLock) {
6059 final Object obj = mSettings.getSettingLPr(appId);
6060 if (obj instanceof SharedUserSetting) {
6061 final SharedUserSetting sus = (SharedUserSetting) obj;
6062 return sus.pkgFlags;
6063 } else if (obj instanceof PackageSetting) {
6064 final PackageSetting ps = (PackageSetting) obj;
6065 if (shouldFilterApplicationLocked(
6066 ps, callingUid, UserHandle.getUserId(callingUid))) {
6076 public int getPrivateFlagsForUid(int uid) {
6077 final int callingUid = Binder.getCallingUid();
6078 if (getInstantAppPackageName(callingUid) != null) {
6081 final int appId = UserHandle.getAppId(uid);
6082 synchronized (mLock) {
6083 final Object obj = mSettings.getSettingLPr(appId);
6084 if (obj instanceof SharedUserSetting) {
6085 final SharedUserSetting sus = (SharedUserSetting) obj;
6086 return sus.pkgPrivateFlags;
6087 } else if (obj instanceof PackageSetting) {
6088 final PackageSetting ps = (PackageSetting) obj;
6089 if (shouldFilterApplicationLocked(
6090 ps, callingUid, UserHandle.getUserId(callingUid))) {
6093 return ps.pkgPrivateFlags;
6100 public boolean isUidPrivileged(int uid) {
6101 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6104 final int appId = UserHandle.getAppId(uid);
6106 synchronized (mLock) {
6107 final Object obj = mSettings.getSettingLPr(appId);
6108 if (obj instanceof SharedUserSetting) {
6109 final SharedUserSetting sus = (SharedUserSetting) obj;
6110 final Iterator<PackageSetting> it = sus.packages.iterator();
6111 while (it.hasNext()) {
6112 if (it.next().isPrivileged()) {
6116 } else if (obj instanceof PackageSetting) {
6117 final PackageSetting ps = (PackageSetting) obj;
6118 return ps.isPrivileged();
6124 // NOTE: Can't remove due to unsupported app usage
6126 public String[] getAppOpPermissionPackages(String permName) {
6128 // Because this is accessed via the package manager service AIDL,
6129 // go through the permission manager service AIDL
6130 return mPermissionManagerService.getAppOpPermissionPackages(permName);
6131 } catch (RemoteException ignore) { }
6136 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
6137 int flags, int userId) {
6138 return resolveIntentInternal(intent, resolvedType, flags, 0 /*privateResolveFlags*/,
6139 userId, false, Binder.getCallingUid());
6143 * Normally instant apps can only be resolved when they're visible to the caller.
6144 * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
6145 * since we need to allow the system to start any installed application.
6147 private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType, int flags,
6148 @PrivateResolveFlags int privateResolveFlags, int userId, boolean resolveForStart,
6149 int filterCallingUid) {
6151 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
6153 if (!mUserManager.exists(userId)) return null;
6154 final int callingUid = Binder.getCallingUid();
6155 flags = updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart);
6156 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
6157 false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
6159 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6160 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
6161 flags, privateResolveFlags, filterCallingUid, userId, resolveForStart,
6162 true /*allowDynamicSplits*/);
6163 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6165 final ResolveInfo bestChoice =
6167 intent, resolvedType, flags, privateResolveFlags, query, userId);
6170 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6175 public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
6176 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
6177 throw new SecurityException(
6178 "findPersistentPreferredActivity can only be run by the system");
6180 if (!mUserManager.exists(userId)) {
6183 final int callingUid = Binder.getCallingUid();
6184 intent = updateIntentForResolve(intent);
6185 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
6186 final int flags = updateFlagsForResolve(
6187 0, userId, callingUid, false /*includeInstantApps*/);
6188 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6190 synchronized (mLock) {
6191 return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
6197 public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
6198 IntentFilter filter, int match, ComponentName activity) {
6199 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6202 final int userId = UserHandle.getCallingUserId();
6203 if (DEBUG_PREFERRED) {
6204 Log.v(TAG, "setLastChosenActivity intent=" + intent
6205 + " resolvedType=" + resolvedType
6207 + " filter=" + filter
6209 + " activity=" + activity);
6210 filter.dump(new PrintStreamPrinter(System.out), " ");
6212 intent.setComponent(null);
6213 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6215 // Find any earlier preferred or last chosen entries and nuke them
6216 findPreferredActivityNotLocked(
6217 intent, resolvedType, flags, query, 0, false, true, false, userId);
6218 // Add the new activity as the last chosen for this filter
6219 addPreferredActivityInternal(filter, match, null, activity, false, userId,
6220 "Setting last chosen");
6224 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
6225 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6228 final int userId = UserHandle.getCallingUserId();
6229 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
6230 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6232 return findPreferredActivityNotLocked(
6233 intent, resolvedType, flags, query, 0, false, false, false, userId);
6237 * Returns whether or not instant apps have been disabled remotely.
6239 private boolean areWebInstantAppsDisabled(int userId) {
6240 return mWebInstantAppsDisabled.get(userId);
6243 private boolean isInstantAppResolutionAllowed(
6244 Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6245 boolean skipPackageCheck) {
6246 if (mInstantAppResolverConnection == null) {
6249 if (mInstantAppInstallerActivity == null) {
6252 if (intent.getComponent() != null) {
6255 if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6258 if (!skipPackageCheck && intent.getPackage() != null) {
6261 if (!intent.isWebIntent()) {
6262 // for non web intents, we should not resolve externally if an app already exists to
6263 // handle it or if the caller didn't explicitly request it.
6264 if ((resolvedActivities != null && resolvedActivities.size() != 0)
6265 || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) == 0) {
6269 if (intent.getData() == null || TextUtils.isEmpty(intent.getData().getHost())) {
6271 } else if (areWebInstantAppsDisabled(userId)) {
6275 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6276 // Or if there's already an ephemeral app installed that handles the action
6277 synchronized (mLock) {
6278 final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6279 for (int n = 0; n < count; n++) {
6280 final ResolveInfo info = resolvedActivities.get(n);
6281 final String packageName = info.activityInfo.packageName;
6282 final PackageSetting ps = mSettings.mPackages.get(packageName);
6284 // only check domain verification status if the app is not a browser
6285 if (!info.handleAllWebDataURI) {
6286 // Try to get the status from User settings first
6287 final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6288 final int status = (int) (packedStatus >> 32);
6289 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6290 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6291 if (DEBUG_INSTANT) {
6292 Slog.v(TAG, "DENY instant app;"
6293 + " pkg: " + packageName + ", status: " + status);
6298 if (ps.getInstantApp(userId)) {
6299 if (DEBUG_INSTANT) {
6300 Slog.v(TAG, "DENY instant app installed;"
6301 + " pkg: " + packageName);
6308 // We've exhausted all ways to deny ephemeral application; let the system look for them.
6312 private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6313 Intent origIntent, String resolvedType, String callingPackage,
6314 @Nullable String callingFeatureId, boolean isRequesterInstantApp,
6315 Bundle verificationBundle, int userId) {
6316 final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6317 new InstantAppRequest(responseObj, origIntent, resolvedType,
6318 callingPackage, callingFeatureId, isRequesterInstantApp, userId, verificationBundle,
6319 false /*resolveForStart*/, responseObj.hostDigestPrefixSecure,
6320 responseObj.token));
6321 mHandler.sendMessage(msg);
6324 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6325 int flags, int privateResolveFlags, List<ResolveInfo> query, int userId) {
6326 if (query != null) {
6327 final int N = query.size();
6329 return query.get(0);
6331 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6332 // If there is more than one activity with the same priority,
6333 // then let the user decide between them.
6334 ResolveInfo r0 = query.get(0);
6335 ResolveInfo r1 = query.get(1);
6336 if (DEBUG_INTENT_MATCHING || debug) {
6337 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6338 + r1.activityInfo.name + "=" + r1.priority);
6340 // If the first activity has a higher priority, or a different
6341 // default, then it is always desirable to pick it.
6342 if (r0.priority != r1.priority
6343 || r0.preferredOrder != r1.preferredOrder
6344 || r0.isDefault != r1.isDefault) {
6345 return query.get(0);
6347 // If we have saved a preference for a preferred activity for
6348 // this Intent, use that.
6349 ResolveInfo ri = findPreferredActivityNotLocked(intent, resolvedType,
6350 flags, query, r0.priority, true, false, debug, userId);
6354 // If we have an ephemeral app, use it
6355 for (int i = 0; i < N; i++) {
6357 if (ri.activityInfo.applicationInfo.isInstantApp()) {
6358 final String packageName = ri.activityInfo.packageName;
6359 final PackageSetting ps = mSettings.mPackages.get(packageName);
6360 final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6361 final int status = (int)(packedStatus >> 32);
6362 if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6367 if ((privateResolveFlags
6368 & PackageManagerInternal.RESOLVE_NON_RESOLVER_ONLY) != 0) {
6371 ri = new ResolveInfo(mResolveInfo);
6372 ri.activityInfo = new ActivityInfo(ri.activityInfo);
6373 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6374 // If all of the options come from the same package, show the application's
6375 // label and icon instead of the generic resolver's.
6376 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6377 // and then throw away the ResolveInfo itself, meaning that the caller loses
6378 // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6379 // a fallback for this case; we only set the target package's resources on
6380 // the ResolveInfo, not the ActivityInfo.
6381 final String intentPackage = intent.getPackage();
6382 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6383 final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6384 ri.resolvePackageName = intentPackage;
6385 if (userNeedsBadging(userId)) {
6386 ri.noResourceId = true;
6388 ri.icon = appi.icon;
6390 ri.iconResourceId = appi.icon;
6391 ri.labelRes = appi.labelRes;
6393 ri.activityInfo.applicationInfo = new ApplicationInfo(
6394 ri.activityInfo.applicationInfo);
6396 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6397 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6399 // Make sure that the resolver is displayable in car mode
6400 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6401 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6409 * Return true if the given list is not empty and all of its contents have
6410 * an activityInfo with the given package name.
6412 private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6413 if (ArrayUtils.isEmpty(list)) {
6416 for (int i = 0, N = list.size(); i < N; i++) {
6417 final ResolveInfo ri = list.get(i);
6418 final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6419 if (ai == null || !packageName.equals(ai.packageName)) {
6427 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6428 int flags, List<ResolveInfo> query, boolean debug, int userId) {
6429 final int N = query.size();
6430 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6432 // Get the list of persistent preferred activities that handle the intent
6433 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6434 List<PersistentPreferredActivity> pprefs = ppir != null
6435 ? ppir.queryIntent(intent, resolvedType,
6436 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6439 if (pprefs != null && pprefs.size() > 0) {
6440 final int M = pprefs.size();
6441 for (int i=0; i<M; i++) {
6442 final PersistentPreferredActivity ppa = pprefs.get(i);
6443 if (DEBUG_PREFERRED || debug) {
6444 Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6445 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6446 + "\n component=" + ppa.mComponent);
6447 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6449 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6450 flags | MATCH_DISABLED_COMPONENTS, userId);
6451 if (DEBUG_PREFERRED || debug) {
6452 Slog.v(TAG, "Found persistent preferred activity:");
6454 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6456 Slog.v(TAG, " null");
6460 // This previously registered persistent preferred activity
6461 // component is no longer known. Ignore it and do NOT remove it.
6464 for (int j=0; j<N; j++) {
6465 final ResolveInfo ri = query.get(j);
6466 if (!ri.activityInfo.applicationInfo.packageName
6467 .equals(ai.applicationInfo.packageName)) {
6470 if (!ri.activityInfo.name.equals(ai.name)) {
6473 // Found a persistent preference that can handle the intent.
6474 if (DEBUG_PREFERRED || debug) {
6475 Slog.v(TAG, "Returning persistent preferred activity: " +
6476 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6485 private boolean isHomeIntent(Intent intent) {
6486 return ACTION_MAIN.equals(intent.getAction())
6487 && intent.hasCategory(CATEGORY_HOME)
6488 && intent.hasCategory(CATEGORY_DEFAULT);
6491 // TODO: handle preferred activities missing while user has amnesia
6492 /** <b>must not hold {@link #mLock}</b> */
6493 ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
6494 List<ResolveInfo> query, int priority, boolean always,
6495 boolean removeMatches, boolean debug, int userId) {
6496 if (Thread.holdsLock(mLock)) {
6497 Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
6498 + " is holding mLock", new Throwable());
6500 if (!mUserManager.exists(userId)) return null;
6501 final int callingUid = Binder.getCallingUid();
6502 // Do NOT hold the packages lock; this calls up into the settings provider which
6503 // could cause a deadlock.
6504 final boolean isDeviceProvisioned =
6505 android.provider.Settings.Global.getInt(mContext.getContentResolver(),
6506 android.provider.Settings.Global.DEVICE_PROVISIONED, 0) == 1;
6507 flags = updateFlagsForResolve(
6508 flags, userId, callingUid, false /*includeInstantApps*/);
6509 intent = updateIntentForResolve(intent);
6511 synchronized (mLock) {
6512 // Try to find a matching persistent preferred activity.
6513 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6516 // If a persistent preferred activity matched, use it.
6521 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6522 // Get the list of preferred activities that handle the intent
6523 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6524 List<PreferredActivity> prefs = pir != null
6525 ? pir.queryIntent(intent, resolvedType,
6526 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6529 if (prefs != null && prefs.size() > 0) {
6530 boolean changed = false;
6532 // First figure out how good the original match set is.
6533 // We will only allow preferred activities that came
6534 // from the same match quality.
6537 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6539 final int N = query.size();
6540 for (int j=0; j<N; j++) {
6541 final ResolveInfo ri = query.get(j);
6542 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6543 + ": 0x" + Integer.toHexString(match));
6544 if (ri.match > match) {
6549 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6550 + Integer.toHexString(match));
6552 match &= IntentFilter.MATCH_CATEGORY_MASK;
6553 final int M = prefs.size();
6554 for (int i=0; i<M; i++) {
6555 final PreferredActivity pa = prefs.get(i);
6556 if (DEBUG_PREFERRED || debug) {
6557 Slog.v(TAG, "Checking PreferredActivity ds="
6558 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6559 + "\n component=" + pa.mPref.mComponent);
6560 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6562 if (pa.mPref.mMatch != match) {
6563 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6564 + Integer.toHexString(pa.mPref.mMatch));
6567 // If it's not an "always" type preferred activity and that's what we're
6568 // looking for, skip it.
6569 if (always && !pa.mPref.mAlways) {
6570 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6573 final ActivityInfo ai = getActivityInfo(
6574 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6575 | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6577 if (DEBUG_PREFERRED || debug) {
6578 Slog.v(TAG, "Found preferred activity:");
6580 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6582 Slog.v(TAG, " null");
6585 final boolean excludeSetupWizardHomeActivity = isHomeIntent(intent)
6586 && !isDeviceProvisioned;
6588 // Do not remove launcher's preferred activity during SetupWizard
6589 // due to it may not install yet
6590 if (excludeSetupWizardHomeActivity) {
6594 // This previously registered preferred activity
6595 // component is no longer known. Most likely an update
6596 // to the app was installed and in the new version this
6597 // component no longer exists. Clean it up by removing
6598 // it from the preferred activities list, and skip it.
6599 Slog.w(TAG, "Removing dangling preferred activity: "
6600 + pa.mPref.mComponent);
6601 pir.removeFilter(pa);
6605 for (int j=0; j<N; j++) {
6606 final ResolveInfo ri = query.get(j);
6607 if (!ri.activityInfo.applicationInfo.packageName
6608 .equals(ai.applicationInfo.packageName)) {
6611 if (!ri.activityInfo.name.equals(ai.name)) {
6615 if (removeMatches) {
6616 pir.removeFilter(pa);
6618 if (DEBUG_PREFERRED) {
6619 Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6624 // Okay we found a previously set preferred or last chosen app.
6625 // If the result set is different from when this
6626 // was created, and is not a subset of the preferred set, we need to
6627 // clear it and re-ask the user their preference, if we're looking for
6628 // an "always" type entry.
6630 if (always && !pa.mPref.sameSet(query, excludeSetupWizardHomeActivity)) {
6631 if (pa.mPref.isSuperset(query, excludeSetupWizardHomeActivity)) {
6632 if (!excludeSetupWizardHomeActivity) {
6633 // some components of the set are no longer present in
6634 // the query, but the preferred activity can still be reused
6635 if (DEBUG_PREFERRED) {
6636 Slog.i(TAG, "Result set changed, but PreferredActivity"
6637 + " is still valid as only non-preferred"
6638 + " components were removed for " + intent
6639 + " type " + resolvedType);
6641 // remove obsolete components and re-add the up-to-date
6643 PreferredActivity freshPa = new PreferredActivity(pa,
6645 pa.mPref.discardObsoleteComponents(query),
6646 pa.mPref.mComponent,
6648 pir.removeFilter(pa);
6649 pir.addFilter(freshPa);
6652 if (DEBUG_PREFERRED) {
6653 Slog.i(TAG, "Do not remove preferred activity for launcher"
6654 + " during SetupWizard");
6659 "Result set changed, dropping preferred activity for "
6660 + intent + " type " + resolvedType);
6661 if (DEBUG_PREFERRED) {
6662 Slog.v(TAG, "Removing preferred activity since set changed "
6663 + pa.mPref.mComponent);
6665 pir.removeFilter(pa);
6666 // Re-add the filter as a "last chosen" entry (!always)
6667 PreferredActivity lastChosen = new PreferredActivity(
6668 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6669 pir.addFilter(lastChosen);
6675 // Yay! Either the set matched or we're looking for the last chosen
6676 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6677 + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6683 if (DEBUG_PREFERRED) {
6684 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6686 scheduleWritePackageRestrictionsLocked(userId);
6691 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6696 * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6699 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6701 mContext.enforceCallingOrSelfPermission(
6702 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6703 List<CrossProfileIntentFilter> matches =
6704 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6705 if (matches != null) {
6706 int size = matches.size();
6707 for (int i = 0; i < size; i++) {
6708 if (matches.get(i).getTargetUserId() == targetUserId) return true;
6711 if (intent.hasWebURI()) {
6712 // cross-profile app linking works only towards the parent.
6713 final int callingUid = Binder.getCallingUid();
6714 final UserInfo parent = getProfileParent(sourceUserId);
6715 if (parent == null) {
6718 synchronized (mLock) {
6719 int flags = updateFlagsForResolve(0, parent.id, callingUid,
6720 false /*includeInstantApps*/);
6721 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6722 intent, resolvedType, flags, sourceUserId, parent.id);
6723 return xpDomainInfo != null;
6729 private UserInfo getProfileParent(int userId) {
6730 final long identity = Binder.clearCallingIdentity();
6732 return mUserManager.getProfileParent(userId);
6734 Binder.restoreCallingIdentity(identity);
6738 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6739 String resolvedType, int userId) {
6740 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6741 if (resolver != null) {
6742 return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6748 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6749 String resolvedType, int flags, int userId) {
6751 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6753 return new ParceledListSlice<>(
6754 queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6756 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6761 * Returns the package name of the calling Uid if it's an instant app. If it isn't
6762 * instant, returns {@code null}.
6764 private String getInstantAppPackageName(int callingUid) {
6765 synchronized (mLock) {
6766 // If the caller is an isolated app use the owner's uid for the lookup.
6767 if (Process.isIsolated(callingUid)) {
6768 callingUid = mIsolatedOwners.get(callingUid);
6770 final int appId = UserHandle.getAppId(callingUid);
6771 final Object obj = mSettings.getSettingLPr(appId);
6772 if (obj instanceof PackageSetting) {
6773 final PackageSetting ps = (PackageSetting) obj;
6774 final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6775 return isInstantApp ? ps.pkg.getPackageName() : null;
6781 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6782 String resolvedType, int flags, int userId) {
6783 return queryIntentActivitiesInternal(
6784 intent, resolvedType, flags, 0 /*privateResolveFlags*/, Binder.getCallingUid(),
6785 userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
6788 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6789 String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags,
6790 int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits) {
6791 if (!mUserManager.exists(userId)) return Collections.emptyList();
6792 final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
6793 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
6794 false /* requireFullPermission */, false /* checkShell */,
6795 "query intent activities");
6796 final String pkgName = intent.getPackage();
6797 ComponentName comp = intent.getComponent();
6799 if (intent.getSelector() != null) {
6800 intent = intent.getSelector();
6801 comp = intent.getComponent();
6805 flags = updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart,
6806 comp != null || pkgName != null /*onlyExposedExplicitly*/);
6808 final List<ResolveInfo> list = new ArrayList<>(1);
6809 final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6811 // When specifying an explicit component, we prevent the activity from being
6812 // used when either 1) the calling package is normal and the activity is within
6813 // an ephemeral application or 2) the calling package is ephemeral and the
6814 // activity is not visible to ephemeral applications.
6815 final boolean matchInstantApp =
6816 (flags & PackageManager.MATCH_INSTANT) != 0;
6817 final boolean matchVisibleToInstantAppOnly =
6818 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6819 final boolean matchExplicitlyVisibleOnly =
6820 (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
6821 final boolean isCallerInstantApp =
6822 instantAppPkgName != null;
6823 final boolean isTargetSameInstantApp =
6824 comp.getPackageName().equals(instantAppPkgName);
6825 final boolean isTargetInstantApp =
6826 (ai.applicationInfo.privateFlags
6827 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6828 final boolean isTargetVisibleToInstantApp =
6829 (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
6830 final boolean isTargetExplicitlyVisibleToInstantApp =
6831 isTargetVisibleToInstantApp
6832 && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
6833 final boolean isTargetHiddenFromInstantApp =
6834 !isTargetVisibleToInstantApp
6835 || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
6836 final boolean blockResolution =
6837 !isTargetSameInstantApp
6838 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6839 || (matchVisibleToInstantAppOnly && isCallerInstantApp
6840 && isTargetHiddenFromInstantApp));
6841 if (!blockResolution) {
6842 final ResolveInfo ri = new ResolveInfo();
6843 ri.activityInfo = ai;
6848 List<ResolveInfo> result = applyPostResolutionFilter(
6849 list, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,
6855 boolean sortResult = false;
6856 boolean addInstant = false;
6857 List<ResolveInfo> result;
6858 synchronized (mLock) {
6859 if (pkgName == null) {
6860 List<CrossProfileIntentFilter> matchingFilters =
6861 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6862 // Check for results that need to skip the current profile.
6863 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
6864 resolvedType, flags, userId);
6865 if (xpResolveInfo != null) {
6866 List<ResolveInfo> xpResult = new ArrayList<>(1);
6867 xpResult.add(xpResolveInfo);
6868 return applyPostResolutionFilter(
6869 filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
6870 allowDynamicSplits, filterCallingUid, resolveForStart, userId, intent);
6873 // Check for results in the current profile.
6874 result = filterIfNotSystemUser(mComponentResolver.queryActivities(
6875 intent, resolvedType, flags, privateResolveFlags, userId), userId);
6876 addInstant = isInstantAppResolutionAllowed(intent, result, userId,
6877 false /*skipPackageCheck*/);
6878 // Check for cross profile results.
6879 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6880 xpResolveInfo = queryCrossProfileIntents(
6881 matchingFilters, intent, resolvedType, flags, userId,
6882 hasNonNegativePriorityResult);
6883 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6884 boolean isVisibleToUser = filterIfNotSystemUser(
6885 Collections.singletonList(xpResolveInfo), userId).size() > 0;
6886 if (isVisibleToUser) {
6887 result.add(xpResolveInfo);
6891 if (intent.hasWebURI()) {
6892 CrossProfileDomainInfo xpDomainInfo = null;
6893 final UserInfo parent = getProfileParent(userId);
6894 if (parent != null) {
6895 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6896 flags, userId, parent.id);
6898 if (xpDomainInfo != null) {
6899 if (xpResolveInfo != null) {
6900 // If we didn't remove it, the cross-profile ResolveInfo would be twice
6902 result.remove(xpResolveInfo);
6904 if (result.size() == 0 && !addInstant) {
6905 // No result in current profile, but found candidate in parent user.
6906 // And we are not going to add emphemeral app, so we can return the
6907 // result straight away.
6908 result.add(xpDomainInfo.resolveInfo);
6909 return applyPostResolutionFilter(result, instantAppPkgName,
6910 allowDynamicSplits, filterCallingUid, resolveForStart, userId,
6913 } else if (result.size() <= 1 && !addInstant) {
6914 // No result in parent user and <= 1 result in current profile, and we
6915 // are not going to add emphemeral app, so we can return the result without
6916 // further processing.
6917 return applyPostResolutionFilter(result, instantAppPkgName,
6918 allowDynamicSplits, filterCallingUid, resolveForStart, userId,
6921 // We have more than one candidate (combining results from current and parent
6922 // profile), so we need filtering and sorting.
6923 result = filterCandidatesWithDomainPreferredActivitiesLPr(
6924 intent, flags, result, xpDomainInfo, userId);
6928 final AndroidPackage pkg = mPackages.get(pkgName);
6931 result = filterIfNotSystemUser(mComponentResolver.queryActivities(
6932 intent, resolvedType, flags, pkg.getActivities(), userId), userId);
6934 if (result == null || result.size() == 0) {
6935 // the caller wants to resolve for a particular package; however, there
6936 // were no installed results, so, try to find an ephemeral result
6937 addInstant = isInstantAppResolutionAllowed(
6938 intent, null /*result*/, userId, true /*skipPackageCheck*/);
6939 if (result == null) {
6940 result = new ArrayList<>();
6946 String callingPkgName = getInstantAppPackageName(filterCallingUid);
6947 boolean isRequesterInstantApp = isInstantApp(callingPkgName, userId);
6948 result = maybeAddInstantAppInstaller(result, intent, resolvedType, flags, userId,
6949 resolveForStart, isRequesterInstantApp);
6952 Collections.sort(result, RESOLVE_PRIORITY_SORTER);
6954 return applyPostResolutionFilter(
6955 result, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,
6959 private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
6960 String resolvedType, int flags, int userId, boolean resolveForStart,
6961 boolean isRequesterInstantApp) {
6962 // first, check to see if we've got an instant app already installed
6963 final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
6964 ResolveInfo localInstantApp = null;
6965 boolean blockResolution = false;
6966 if (!alreadyResolvedLocally) {
6967 final List<ResolveInfo> instantApps = mComponentResolver.queryActivities(
6971 | PackageManager.GET_RESOLVED_FILTER
6972 | PackageManager.MATCH_INSTANT
6973 | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
6975 for (int i = instantApps.size() - 1; i >= 0; --i) {
6976 final ResolveInfo info = instantApps.get(i);
6977 final String packageName = info.activityInfo.packageName;
6978 final PackageSetting ps = mSettings.mPackages.get(packageName);
6979 if (ps.getInstantApp(userId)) {
6980 final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6981 final int status = (int)(packedStatus >> 32);
6982 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6983 // there's a local instant application installed, but, the user has
6984 // chosen to never use it; skip resolution and don't acknowledge
6985 // an instant application is even available
6986 if (DEBUG_INSTANT) {
6987 Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
6989 blockResolution = true;
6992 // we have a locally installed instant application; skip resolution
6993 // but acknowledge there's an instant application available
6994 if (DEBUG_INSTANT) {
6995 Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
6997 localInstantApp = info;
7003 // no app installed, let's see if one's available
7004 AuxiliaryResolveInfo auxiliaryResponse = null;
7005 if (!blockResolution) {
7006 if (localInstantApp == null) {
7007 // we don't have an instant app locally, resolve externally
7008 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
7009 String token = UUID.randomUUID().toString();
7010 InstantAppDigest digest = InstantAppResolver.parseDigest(intent);
7011 final InstantAppRequest requestObject = new InstantAppRequest(null /*responseObj*/,
7012 intent /*origIntent*/, resolvedType, null /*callingPackage*/,
7013 null /*callingFeatureId*/, isRequesterInstantApp, userId,
7014 null /*verificationBundle*/, resolveForStart,
7015 digest.getDigestPrefixSecure(), token);
7016 auxiliaryResponse = InstantAppResolver.doInstantAppResolutionPhaseOne(
7017 mInstantAppResolverConnection, requestObject);
7018 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7020 // we have an instant application locally, but, we can't admit that since
7021 // callers shouldn't be able to determine prior browsing. create a dummy
7022 // auxiliary response so the downstream code behaves as if there's an
7023 // instant application available externally. when it comes time to start
7024 // the instant application, we'll do the right thing.
7025 final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
7026 auxiliaryResponse = new AuxiliaryResolveInfo(null /* failureActivity */,
7027 ai.packageName, ai.longVersionCode, null /* splitName */);
7030 if (intent.isWebIntent() && auxiliaryResponse == null) {
7033 final PackageSetting ps = mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
7035 || !ps.readUserState(userId).isEnabled(mInstantAppInstallerActivity, 0)) {
7038 final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
7039 ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
7040 mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
7041 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7042 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7043 // add a non-generic filter
7044 ephemeralInstaller.filter = new IntentFilter();
7045 if (intent.getAction() != null) {
7046 ephemeralInstaller.filter.addAction(intent.getAction());
7048 if (intent.getData() != null && intent.getData().getPath() != null) {
7049 ephemeralInstaller.filter.addDataPath(
7050 intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
7052 ephemeralInstaller.isInstantAppAvailable = true;
7053 // make sure this resolver is the default
7054 ephemeralInstaller.isDefault = true;
7055 ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
7056 if (DEBUG_INSTANT) {
7057 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7060 result.add(ephemeralInstaller);
7064 private static class CrossProfileDomainInfo {
7065 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
7066 ResolveInfo resolveInfo;
7067 /* Best domain verification status of the activities found in the other profile */
7068 int bestDomainVerificationStatus;
7071 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
7072 String resolvedType, int flags, int sourceUserId, int parentUserId) {
7073 if (!mUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
7077 List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent,
7078 resolvedType, flags, 0, parentUserId);
7080 if (resultTargetUser == null || resultTargetUser.isEmpty()) {
7083 CrossProfileDomainInfo result = null;
7084 int size = resultTargetUser.size();
7085 for (int i = 0; i < size; i++) {
7086 ResolveInfo riTargetUser = resultTargetUser.get(i);
7087 // Intent filter verification is only for filters that specify a host. So don't return
7088 // those that handle all web uris.
7089 if (riTargetUser.handleAllWebDataURI) {
7092 String packageName = riTargetUser.activityInfo.packageName;
7093 PackageSetting ps = mSettings.mPackages.get(packageName);
7097 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
7098 int status = (int)(verificationState >> 32);
7099 if (result == null) {
7100 result = new CrossProfileDomainInfo();
7101 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
7102 sourceUserId, parentUserId);
7103 result.bestDomainVerificationStatus = status;
7105 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
7106 result.bestDomainVerificationStatus);
7109 // Don't consider matches with status NEVER across profiles.
7110 if (result != null && result.bestDomainVerificationStatus
7111 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7118 * Verification statuses are ordered from the worse to the best, except for
7119 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
7121 private int bestDomainVerificationStatus(int status1, int status2) {
7122 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7125 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7128 return (int) MathUtils.max(status1, status2);
7131 private boolean isUserEnabled(int userId) {
7132 long callingId = Binder.clearCallingIdentity();
7134 UserInfo userInfo = mUserManager.getUserInfo(userId);
7135 return userInfo != null && userInfo.isEnabled();
7137 Binder.restoreCallingIdentity(callingId);
7142 * Filter out activities with systemUserOnly flag set, when current user is not System.
7144 * @return filtered list
7146 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
7147 if (userId == UserHandle.USER_SYSTEM) {
7148 return resolveInfos;
7150 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7151 ResolveInfo info = resolveInfos.get(i);
7152 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
7153 resolveInfos.remove(i);
7156 return resolveInfos;
7160 * Filters out ephemeral activities.
7161 * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
7162 * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
7164 * @param resolveInfos The pre-filtered list of resolved activities
7165 * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
7168 * @return A filtered list of resolved activities.
7170 private List<ResolveInfo> applyPostResolutionFilter(@NonNull List<ResolveInfo> resolveInfos,
7171 String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
7172 boolean resolveForStart, int userId, Intent intent) {
7173 final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled(userId);
7174 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7175 final ResolveInfo info = resolveInfos.get(i);
7176 // remove locally resolved instant app web results when disabled
7177 if (info.isInstantAppAvailable && blockInstant) {
7178 resolveInfos.remove(i);
7181 // allow activities that are defined in the provided package
7182 if (allowDynamicSplits
7183 && info.activityInfo != null
7184 && info.activityInfo.splitName != null
7185 && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
7186 info.activityInfo.splitName)) {
7187 if (mInstantAppInstallerActivity == null) {
7188 if (DEBUG_INSTALL) {
7189 Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
7191 resolveInfos.remove(i);
7194 if (blockInstant && isInstantApp(info.activityInfo.packageName, userId)) {
7195 resolveInfos.remove(i);
7198 // requested activity is defined in a split that hasn't been installed yet.
7199 // add the installer to the resolve list
7200 if (DEBUG_INSTALL) {
7201 Slog.v(TAG, "Adding installer to the ResolveInfo list");
7203 final ResolveInfo installerInfo = new ResolveInfo(
7204 mInstantAppInstallerInfo);
7205 final ComponentName installFailureActivity = findInstallFailureActivity(
7206 info.activityInfo.packageName, filterCallingUid, userId);
7207 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7208 installFailureActivity,
7209 info.activityInfo.packageName,
7210 info.activityInfo.applicationInfo.longVersionCode,
7211 info.activityInfo.splitName);
7212 // add a non-generic filter
7213 installerInfo.filter = new IntentFilter();
7215 // This resolve info may appear in the chooser UI, so let us make it
7216 // look as the one it replaces as far as the user is concerned which
7217 // requires loading the correct label and icon for the resolve info.
7218 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7219 installerInfo.labelRes = info.resolveLabelResId();
7220 installerInfo.icon = info.resolveIconResId();
7221 installerInfo.isInstantAppAvailable = true;
7222 resolveInfos.set(i, installerInfo);
7225 // caller is a full app, don't need to apply any other filtering
7226 if (ephemeralPkgName == null) {
7228 } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
7229 // caller is same app; don't need to apply any other filtering
7231 } else if (resolveForStart
7232 && (intent.isWebIntent()
7233 || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0)
7234 && intent.getPackage() == null
7235 && intent.getComponent() == null) {
7236 // ephemeral apps can launch other ephemeral apps indirectly
7239 // allow activities that have been explicitly exposed to ephemeral apps
7240 final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
7242 && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7245 resolveInfos.remove(i);
7247 return resolveInfos;
7251 * Returns the activity component that can handle install failures.
7252 * <p>By default, the instant application installer handles failures. However, an
7253 * application may want to handle failures on its own. Applications do this by
7254 * creating an activity with an intent filter that handles the action
7255 * {@link Intent#ACTION_INSTALL_FAILURE}.
7257 private @Nullable ComponentName findInstallFailureActivity(
7258 String packageName, int filterCallingUid, int userId) {
7259 final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
7260 failureActivityIntent.setPackage(packageName);
7261 // IMPORTANT: disallow dynamic splits to avoid an infinite loop
7262 final List<ResolveInfo> result = queryIntentActivitiesInternal(
7263 failureActivityIntent, null /*resolvedType*/, 0 /*flags*/,
7264 0 /*privateResolveFlags*/, filterCallingUid, userId, false /*resolveForStart*/,
7265 false /*allowDynamicSplits*/);
7266 final int NR = result.size();
7268 for (int i = 0; i < NR; i++) {
7269 final ResolveInfo info = result.get(i);
7270 if (info.activityInfo.splitName != null) {
7273 return new ComponentName(packageName, info.activityInfo.name);
7280 * @param resolveInfos list of resolve infos in descending priority order
7281 * @return if the list contains a resolve info with non-negative priority
7283 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
7284 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
7287 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
7288 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
7290 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
7292 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7293 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
7297 final ArrayList<ResolveInfo> result = new ArrayList<>();
7298 final ArrayList<ResolveInfo> alwaysList = new ArrayList<>();
7299 final ArrayList<ResolveInfo> undefinedList = new ArrayList<>();
7300 final ArrayList<ResolveInfo> alwaysAskList = new ArrayList<>();
7301 final ArrayList<ResolveInfo> neverList = new ArrayList<>();
7302 final ArrayList<ResolveInfo> matchAllList = new ArrayList<>();
7304 synchronized (mLock) {
7305 final int count = candidates.size();
7306 // First, try to use linked apps. Partition the candidates into four lists:
7307 // one for the final results, one for the "do not use ever", one for "undefined status"
7308 // and finally one for "browser app type".
7309 for (int n=0; n<count; n++) {
7310 ResolveInfo info = candidates.get(n);
7311 String packageName = info.activityInfo.packageName;
7312 PackageSetting ps = mSettings.mPackages.get(packageName);
7314 // Add to the special match all list (Browser use case)
7315 if (info.handleAllWebDataURI) {
7316 matchAllList.add(info);
7319 // Try to get the status from User settings first
7320 long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7321 int status = (int)(packedStatus >> 32);
7322 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7323 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
7324 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7325 Slog.i(TAG, " + always: " + info.activityInfo.packageName
7326 + " : linkgen=" + linkGeneration);
7328 // Use link-enabled generation as preferredOrder, i.e.
7329 // prefer newly-enabled over earlier-enabled.
7330 info.preferredOrder = linkGeneration;
7331 alwaysList.add(info);
7332 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7333 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7334 Slog.i(TAG, " + never: " + info.activityInfo.packageName);
7336 neverList.add(info);
7337 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7338 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7339 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName);
7341 alwaysAskList.add(info);
7342 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7343 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7344 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7345 Slog.i(TAG, " + ask: " + info.activityInfo.packageName);
7347 undefinedList.add(info);
7352 // We'll want to include browser possibilities in a few cases
7353 boolean includeBrowser = false;
7355 // First try to add the "always" resolution(s) for the current user, if any
7356 if (alwaysList.size() > 0) {
7357 result.addAll(alwaysList);
7359 // Add all undefined apps as we want them to appear in the disambiguation dialog.
7360 result.addAll(undefinedList);
7361 // Maybe add one for the other profile.
7362 if (xpDomainInfo != null && (
7363 xpDomainInfo.bestDomainVerificationStatus
7364 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7365 result.add(xpDomainInfo.resolveInfo);
7367 includeBrowser = true;
7370 // The presence of any 'always ask' alternatives means we'll also offer browsers.
7371 // If there were 'always' entries their preferred order has been set, so we also
7372 // back that off to make the alternatives equivalent
7373 if (alwaysAskList.size() > 0) {
7374 for (ResolveInfo i : result) {
7375 i.preferredOrder = 0;
7377 result.addAll(alwaysAskList);
7378 includeBrowser = true;
7381 if (includeBrowser) {
7382 // Also add browsers (all of them or only the default one)
7383 if (DEBUG_DOMAIN_VERIFICATION) {
7384 Slog.v(TAG, " ...including browsers in candidate set");
7386 if ((matchFlags & MATCH_ALL) != 0) {
7387 result.addAll(matchAllList);
7389 // Browser/generic handling case. If there's a default browser, go straight
7390 // to that (but only if there is no other higher-priority match).
7391 final String defaultBrowserPackageName =
7392 mPermissionManager.getDefaultBrowser(userId);
7393 int maxMatchPrio = 0;
7394 ResolveInfo defaultBrowserMatch = null;
7395 final int numCandidates = matchAllList.size();
7396 for (int n = 0; n < numCandidates; n++) {
7397 ResolveInfo info = matchAllList.get(n);
7398 // track the highest overall match priority...
7399 if (info.priority > maxMatchPrio) {
7400 maxMatchPrio = info.priority;
7402 // ...and the highest-priority default browser match
7403 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7404 if (defaultBrowserMatch == null
7405 || (defaultBrowserMatch.priority < info.priority)) {
7407 Slog.v(TAG, "Considering default browser match " + info);
7409 defaultBrowserMatch = info;
7413 if (defaultBrowserMatch != null
7414 && defaultBrowserMatch.priority >= maxMatchPrio
7415 && !TextUtils.isEmpty(defaultBrowserPackageName))
7418 Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7420 result.add(defaultBrowserMatch);
7422 result.addAll(matchAllList);
7426 // If there is nothing selected, add all candidates and remove the ones that the user
7427 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7428 if (result.size() == 0) {
7429 result.addAll(candidates);
7430 result.removeAll(neverList);
7434 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7435 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7437 for (ResolveInfo info : result) {
7438 Slog.v(TAG, " + " + info.activityInfo);
7444 // Returns a packed value as a long:
7446 // high 'int'-sized word: link status: undefined/ask/never/always.
7447 // low 'int'-sized word: relative priority among 'always' results.
7448 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7449 long result = ps.getDomainVerificationStatusForUser(userId);
7450 // if none available, get the master status
7451 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7452 if (ps.getIntentFilterVerificationInfo() != null) {
7453 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7459 private ResolveInfo querySkipCurrentProfileIntents(
7460 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7461 int flags, int sourceUserId) {
7462 if (matchingFilters != null) {
7463 int size = matchingFilters.size();
7464 for (int i = 0; i < size; i ++) {
7465 CrossProfileIntentFilter filter = matchingFilters.get(i);
7466 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7467 // Checking if there are activities in the target user that can handle the
7469 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7470 resolvedType, flags, sourceUserId);
7471 if (resolveInfo != null) {
7480 // Return matching ResolveInfo in target user if any.
7481 private ResolveInfo queryCrossProfileIntents(
7482 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7483 int flags, int sourceUserId, boolean matchInCurrentProfile) {
7484 if (matchingFilters != null) {
7485 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7486 // match the same intent. For performance reasons, it is better not to
7487 // run queryIntent twice for the same userId
7488 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7489 int size = matchingFilters.size();
7490 for (int i = 0; i < size; i++) {
7491 CrossProfileIntentFilter filter = matchingFilters.get(i);
7492 int targetUserId = filter.getTargetUserId();
7493 boolean skipCurrentProfile =
7494 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7495 boolean skipCurrentProfileIfNoMatchFound =
7496 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7497 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7498 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7499 // Checking if there are activities in the target user that can handle the
7501 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7502 resolvedType, flags, sourceUserId);
7503 if (resolveInfo != null) return resolveInfo;
7504 alreadyTriedUserIds.put(targetUserId, true);
7512 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7513 * will forward the intent to the filter's target user.
7514 * Otherwise, returns null.
7516 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7517 String resolvedType, int flags, int sourceUserId) {
7518 int targetUserId = filter.getTargetUserId();
7519 List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent,
7520 resolvedType, flags, 0, targetUserId);
7521 if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7522 // If all the matches in the target profile are suspended, return null.
7523 for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7524 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7525 & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7526 return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7534 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7535 int sourceUserId, int targetUserId) {
7536 ResolveInfo forwardingResolveInfo = new ResolveInfo();
7537 long ident = Binder.clearCallingIdentity();
7538 boolean targetIsProfile;
7540 targetIsProfile = mUserManager.getUserInfo(targetUserId).isManagedProfile();
7542 Binder.restoreCallingIdentity(ident);
7545 if (targetIsProfile) {
7546 className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7548 className = FORWARD_INTENT_TO_PARENT;
7550 ComponentName forwardingActivityComponentName = new ComponentName(
7551 mAndroidApplication.packageName, className);
7552 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7554 if (!targetIsProfile) {
7555 forwardingActivityInfo.showUserIcon = targetUserId;
7556 forwardingResolveInfo.noResourceId = true;
7558 forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7559 forwardingResolveInfo.priority = 0;
7560 forwardingResolveInfo.preferredOrder = 0;
7561 forwardingResolveInfo.match = 0;
7562 forwardingResolveInfo.isDefault = true;
7563 forwardingResolveInfo.filter = filter;
7564 forwardingResolveInfo.targetUserId = targetUserId;
7565 return forwardingResolveInfo;
7569 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7570 Intent[] specifics, String[] specificTypes, Intent intent,
7571 String resolvedType, int flags, int userId) {
7572 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7573 specificTypes, intent, resolvedType, flags, userId));
7576 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7577 Intent[] specifics, String[] specificTypes, Intent intent,
7578 String resolvedType, int flags, int userId) {
7579 if (!mUserManager.exists(userId)) return Collections.emptyList();
7580 final int callingUid = Binder.getCallingUid();
7581 flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/);
7582 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7583 false /*requireFullPermission*/, false /*checkShell*/,
7584 "query intent activity options");
7585 final String resultsAction = intent.getAction();
7587 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7588 | PackageManager.GET_RESOLVED_FILTER, userId);
7590 if (DEBUG_INTENT_MATCHING) {
7591 Log.v(TAG, "Query " + intent + ": " + results);
7594 int specificsPos = 0;
7597 // todo: note that the algorithm used here is O(N^2). This
7598 // isn't a problem in our current environment, but if we start running
7599 // into situations where we have more than 5 or 10 matches then this
7600 // should probably be changed to something smarter...
7602 // First we go through and resolve each of the specific items
7603 // that were supplied, taking care of removing any corresponding
7604 // duplicate items in the generic resolve list.
7605 if (specifics != null) {
7606 for (int i=0; i<specifics.length; i++) {
7607 final Intent sintent = specifics[i];
7608 if (sintent == null) {
7612 if (DEBUG_INTENT_MATCHING) {
7613 Log.v(TAG, "Specific #" + i + ": " + sintent);
7616 String action = sintent.getAction();
7617 if (resultsAction != null && resultsAction.equals(action)) {
7618 // If this action was explicitly requested, then don't
7619 // remove things that have it.
7623 ResolveInfo ri = null;
7624 ActivityInfo ai = null;
7626 ComponentName comp = sintent.getComponent();
7630 specificTypes != null ? specificTypes[i] : null,
7635 if (ri == mResolveInfo) {
7636 // ACK! Must do something better with this.
7638 ai = ri.activityInfo;
7639 comp = new ComponentName(ai.applicationInfo.packageName,
7642 ai = getActivityInfo(comp, flags, userId);
7648 // Look for any generic query activities that are duplicates
7649 // of this specific one, and remove them from the results.
7650 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7653 for (j=specificsPos; j<N; j++) {
7654 ResolveInfo sri = results.get(j);
7655 if ((sri.activityInfo.name.equals(comp.getClassName())
7656 && sri.activityInfo.applicationInfo.packageName.equals(
7657 comp.getPackageName()))
7658 || (action != null && sri.filter.matchAction(action))) {
7660 if (DEBUG_INTENT_MATCHING) Log.v(
7661 TAG, "Removing duplicate item from " + j
7662 + " due to specific " + specificsPos);
7671 // Add this specific item to its proper place.
7673 ri = new ResolveInfo();
7674 ri.activityInfo = ai;
7676 results.add(specificsPos, ri);
7677 ri.specificIndex = i;
7682 // Now we go through the remaining generic results and remove any
7683 // duplicate actions that are found here.
7685 for (int i=specificsPos; i<N-1; i++) {
7686 final ResolveInfo rii = results.get(i);
7687 if (rii.filter == null) {
7691 // Iterate over all of the actions of this result's intent
7692 // filter... typically this should be just one.
7693 final Iterator<String> it = rii.filter.actionsIterator();
7697 while (it.hasNext()) {
7698 final String action = it.next();
7699 if (resultsAction != null && resultsAction.equals(action)) {
7700 // If this action was explicitly requested, then don't
7701 // remove things that have it.
7704 for (int j=i+1; j<N; j++) {
7705 final ResolveInfo rij = results.get(j);
7706 if (rij.filter != null && rij.filter.hasAction(action)) {
7708 if (DEBUG_INTENT_MATCHING) Log.v(
7709 TAG, "Removing duplicate item from " + j
7710 + " due to action " + action + " at " + i);
7717 // If the caller didn't request filter information, drop it now
7718 // so we don't have to marshall/unmarshall it.
7719 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7724 // Filter out the caller activity if so requested.
7725 if (caller != null) {
7727 for (int i=0; i<N; i++) {
7728 ActivityInfo ainfo = results.get(i).activityInfo;
7729 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7730 && caller.getClassName().equals(ainfo.name)) {
7737 // If the caller didn't request filter information,
7738 // drop them now so we don't have to
7739 // marshall/unmarshall it.
7740 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7742 for (int i=0; i<N; i++) {
7743 results.get(i).filter = null;
7747 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7752 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7753 String resolvedType, int flags, int userId) {
7754 return new ParceledListSlice<>(
7755 queryIntentReceiversInternal(intent, resolvedType, flags, userId,
7756 false /*allowDynamicSplits*/));
7759 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7760 String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
7761 if (!mUserManager.exists(userId)) return Collections.emptyList();
7762 final int callingUid = Binder.getCallingUid();
7763 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7764 false /*requireFullPermission*/, false /*checkShell*/,
7765 "query intent receivers");
7766 final String instantAppPkgName = getInstantAppPackageName(callingUid);
7767 flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/);
7768 ComponentName comp = intent.getComponent();
7770 if (intent.getSelector() != null) {
7771 intent = intent.getSelector();
7772 comp = intent.getComponent();
7776 final List<ResolveInfo> list = new ArrayList<>(1);
7777 final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7779 // When specifying an explicit component, we prevent the activity from being
7780 // used when either 1) the calling package is normal and the activity is within
7781 // an instant application or 2) the calling package is ephemeral and the
7782 // activity is not visible to instant applications.
7783 final boolean matchInstantApp =
7784 (flags & PackageManager.MATCH_INSTANT) != 0;
7785 final boolean matchVisibleToInstantAppOnly =
7786 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7787 final boolean matchExplicitlyVisibleOnly =
7788 (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7789 final boolean isCallerInstantApp =
7790 instantAppPkgName != null;
7791 final boolean isTargetSameInstantApp =
7792 comp.getPackageName().equals(instantAppPkgName);
7793 final boolean isTargetInstantApp =
7794 (ai.applicationInfo.privateFlags
7795 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7796 final boolean isTargetVisibleToInstantApp =
7797 (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7798 final boolean isTargetExplicitlyVisibleToInstantApp =
7799 isTargetVisibleToInstantApp
7800 && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7801 final boolean isTargetHiddenFromInstantApp =
7802 !isTargetVisibleToInstantApp
7803 || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7804 final boolean blockResolution =
7805 !isTargetSameInstantApp
7806 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7807 || (matchVisibleToInstantAppOnly && isCallerInstantApp
7808 && isTargetHiddenFromInstantApp));
7809 if (!blockResolution) {
7810 ResolveInfo ri = new ResolveInfo();
7811 ri.activityInfo = ai;
7815 return applyPostResolutionFilter(
7816 list, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
7821 synchronized (mLock) {
7822 String pkgName = intent.getPackage();
7823 if (pkgName == null) {
7824 final List<ResolveInfo> result =
7825 mComponentResolver.queryReceivers(intent, resolvedType, flags, userId);
7826 if (result == null) {
7827 return Collections.emptyList();
7829 return applyPostResolutionFilter(
7830 result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
7833 final AndroidPackage pkg = mPackages.get(pkgName);
7835 final List<ResolveInfo> result = mComponentResolver.queryReceivers(
7836 intent, resolvedType, flags, pkg.getReceivers(), userId);
7837 if (result == null) {
7838 return Collections.emptyList();
7840 return applyPostResolutionFilter(
7841 result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
7844 return Collections.emptyList();
7849 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7850 final int callingUid = Binder.getCallingUid();
7851 return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
7854 private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7855 int userId, int callingUid) {
7856 if (!mUserManager.exists(userId)) return null;
7857 flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/);
7858 List<ResolveInfo> query = queryIntentServicesInternal(
7859 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7860 if (query != null) {
7861 if (query.size() >= 1) {
7862 // If there is more than one service with the same priority,
7863 // just arbitrarily pick the first one.
7864 return query.get(0);
7871 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7872 String resolvedType, int flags, int userId) {
7873 final int callingUid = Binder.getCallingUid();
7874 return new ParceledListSlice<>(queryIntentServicesInternal(
7875 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7878 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7879 String resolvedType, int flags, int userId, int callingUid,
7880 boolean includeInstantApps) {
7881 if (!mUserManager.exists(userId)) return Collections.emptyList();
7882 mPermissionManager.enforceCrossUserOrProfilePermission(callingUid,
7884 false /*requireFullPermission*/,
7885 false /*checkShell*/,
7886 "query intent receivers");
7887 final String instantAppPkgName = getInstantAppPackageName(callingUid);
7888 flags = updateFlagsForResolve(flags, userId, callingUid, includeInstantApps);
7889 ComponentName comp = intent.getComponent();
7891 if (intent.getSelector() != null) {
7892 intent = intent.getSelector();
7893 comp = intent.getComponent();
7897 final List<ResolveInfo> list = new ArrayList<>(1);
7898 final ServiceInfo si = getServiceInfo(comp, flags, userId);
7900 // When specifying an explicit component, we prevent the service from being
7901 // used when either 1) the service is in an instant application and the
7902 // caller is not the same instant application or 2) the calling package is
7903 // ephemeral and the activity is not visible to ephemeral applications.
7904 final boolean matchInstantApp =
7905 (flags & PackageManager.MATCH_INSTANT) != 0;
7906 final boolean matchVisibleToInstantAppOnly =
7907 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7908 final boolean isCallerInstantApp =
7909 instantAppPkgName != null;
7910 final boolean isTargetSameInstantApp =
7911 comp.getPackageName().equals(instantAppPkgName);
7912 final boolean isTargetInstantApp =
7913 (si.applicationInfo.privateFlags
7914 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7915 final boolean isTargetHiddenFromInstantApp =
7916 (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7917 final boolean blockResolution =
7918 !isTargetSameInstantApp
7919 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7920 || (matchVisibleToInstantAppOnly && isCallerInstantApp
7921 && isTargetHiddenFromInstantApp));
7922 if (!blockResolution) {
7923 final ResolveInfo ri = new ResolveInfo();
7924 ri.serviceInfo = si;
7932 synchronized (mLock) {
7933 String pkgName = intent.getPackage();
7934 if (pkgName == null) {
7935 final List<ResolveInfo> resolveInfos = mComponentResolver.queryServices(intent,
7936 resolvedType, flags, userId);
7937 if (resolveInfos == null) {
7938 return Collections.emptyList();
7940 return applyPostServiceResolutionFilter(
7944 final AndroidPackage pkg = mPackages.get(pkgName);
7946 final List<ResolveInfo> resolveInfos = mComponentResolver.queryServices(intent,
7947 resolvedType, flags, pkg.getServices(),
7949 if (resolveInfos == null) {
7950 return Collections.emptyList();
7952 return applyPostServiceResolutionFilter(
7956 return Collections.emptyList();
7960 private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7961 String instantAppPkgName) {
7962 if (instantAppPkgName == null) {
7963 return resolveInfos;
7965 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7966 final ResolveInfo info = resolveInfos.get(i);
7967 final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7968 // allow services that are defined in the provided package
7969 if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7970 if (info.serviceInfo.splitName != null
7971 && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7972 info.serviceInfo.splitName)) {
7973 // requested service is defined in a split that hasn't been installed yet.
7974 // add the installer to the resolve list
7975 if (DEBUG_INSTANT) {
7976 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7978 final ResolveInfo installerInfo = new ResolveInfo(
7979 mInstantAppInstallerInfo);
7980 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7981 null /* installFailureActivity */,
7982 info.serviceInfo.packageName,
7983 info.serviceInfo.applicationInfo.longVersionCode,
7984 info.serviceInfo.splitName);
7985 // add a non-generic filter
7986 installerInfo.filter = new IntentFilter();
7987 // load resources from the correct package
7988 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7989 resolveInfos.set(i, installerInfo);
7993 // allow services that have been explicitly exposed to ephemeral apps
7995 && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7998 resolveInfos.remove(i);
8000 return resolveInfos;
8004 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
8005 String resolvedType, int flags, int userId) {
8006 return new ParceledListSlice<>(
8007 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
8010 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
8011 Intent intent, String resolvedType, int flags, int userId) {
8012 if (!mUserManager.exists(userId)) return Collections.emptyList();
8013 final int callingUid = Binder.getCallingUid();
8014 final String instantAppPkgName = getInstantAppPackageName(callingUid);
8015 flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/);
8016 ComponentName comp = intent.getComponent();
8018 if (intent.getSelector() != null) {
8019 intent = intent.getSelector();
8020 comp = intent.getComponent();
8024 final List<ResolveInfo> list = new ArrayList<>(1);
8025 final ProviderInfo pi = getProviderInfo(comp, flags, userId);
8027 // When specifying an explicit component, we prevent the provider from being
8028 // used when either 1) the provider is in an instant application and the
8029 // caller is not the same instant application or 2) the calling package is an
8030 // instant application and the provider is not visible to instant applications.
8031 final boolean matchInstantApp =
8032 (flags & PackageManager.MATCH_INSTANT) != 0;
8033 final boolean matchVisibleToInstantAppOnly =
8034 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8035 final boolean isCallerInstantApp =
8036 instantAppPkgName != null;
8037 final boolean isTargetSameInstantApp =
8038 comp.getPackageName().equals(instantAppPkgName);
8039 final boolean isTargetInstantApp =
8040 (pi.applicationInfo.privateFlags
8041 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8042 final boolean isTargetHiddenFromInstantApp =
8043 (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8044 final boolean blockResolution =
8045 !isTargetSameInstantApp
8046 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8047 || (matchVisibleToInstantAppOnly && isCallerInstantApp
8048 && isTargetHiddenFromInstantApp));
8049 if (!blockResolution) {
8050 final ResolveInfo ri = new ResolveInfo();
8051 ri.providerInfo = pi;
8059 synchronized (mLock) {
8060 String pkgName = intent.getPackage();
8061 if (pkgName == null) {
8062 final List<ResolveInfo> resolveInfos = mComponentResolver.queryProviders(intent,
8063 resolvedType, flags, userId);
8064 if (resolveInfos == null) {
8065 return Collections.emptyList();
8067 return applyPostContentProviderResolutionFilter(
8071 final AndroidPackage pkg = mPackages.get(pkgName);
8073 final List<ResolveInfo> resolveInfos = mComponentResolver.queryProviders(intent,
8074 resolvedType, flags,
8075 pkg.getProviders(), userId);
8076 if (resolveInfos == null) {
8077 return Collections.emptyList();
8079 return applyPostContentProviderResolutionFilter(
8083 return Collections.emptyList();
8087 private List<ResolveInfo> applyPostContentProviderResolutionFilter(
8088 List<ResolveInfo> resolveInfos, String instantAppPkgName) {
8089 if (instantAppPkgName == null) {
8090 return resolveInfos;
8092 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8093 final ResolveInfo info = resolveInfos.get(i);
8094 final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
8095 // allow providers that are defined in the provided package
8096 if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
8097 if (info.providerInfo.splitName != null
8098 && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
8099 info.providerInfo.splitName)) {
8100 // requested provider is defined in a split that hasn't been installed yet.
8101 // add the installer to the resolve list
8102 if (DEBUG_INSTANT) {
8103 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8105 final ResolveInfo installerInfo = new ResolveInfo(
8106 mInstantAppInstallerInfo);
8107 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8108 null /*failureActivity*/,
8109 info.providerInfo.packageName,
8110 info.providerInfo.applicationInfo.longVersionCode,
8111 info.providerInfo.splitName);
8112 // add a non-generic filter
8113 installerInfo.filter = new IntentFilter();
8114 // load resources from the correct package
8115 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8116 resolveInfos.set(i, installerInfo);
8120 // allow providers that have been explicitly exposed to instant applications
8122 && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8125 resolveInfos.remove(i);
8127 return resolveInfos;
8131 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
8132 final int callingUid = Binder.getCallingUid();
8133 if (getInstantAppPackageName(callingUid) != null) {
8134 return ParceledListSlice.emptyList();
8136 if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
8137 flags = updateFlagsForPackage(flags, userId);
8138 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8139 final boolean listApex = (flags & MATCH_APEX) != 0;
8140 final boolean listFactory = (flags & MATCH_FACTORY_ONLY) != 0;
8142 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
8143 false /* requireFullPermission */, false /* checkShell */,
8144 "get installed packages");
8147 synchronized (mLock) {
8148 ArrayList<PackageInfo> list;
8149 if (listUninstalled) {
8150 list = new ArrayList<>(mSettings.mPackages.size());
8151 for (PackageSetting ps : mSettings.mPackages.values()) {
8152 if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8155 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
8158 final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8164 list = new ArrayList<>(mPackages.size());
8165 for (AndroidPackage p : mPackages.values()) {
8166 final PackageSetting ps = getPackageSetting(p.getPackageName());
8167 if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8170 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
8173 final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8181 list.addAll(mApexManager.getFactoryPackages());
8183 list.addAll(mApexManager.getActivePackages());
8185 if (listUninstalled) {
8186 list.addAll(mApexManager.getInactivePackages());
8189 return new ParceledListSlice<>(list);
8193 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
8194 String[] permissions, boolean[] tmp, int flags, int userId) {
8196 final PermissionsState permissionsState = ps.getPermissionsState();
8197 for (int i=0; i<permissions.length; i++) {
8198 final String permission = permissions[i];
8199 if (permissionsState.hasPermission(permission, userId)) {
8206 if (numMatch == 0) {
8209 final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8211 // The above might return null in cases of uninstalled apps or install-state
8212 // skew across users/profiles.
8214 if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
8215 if (numMatch == permissions.length) {
8216 pi.requestedPermissions = permissions;
8218 pi.requestedPermissions = new String[numMatch];
8220 for (int i=0; i<permissions.length; i++) {
8222 pi.requestedPermissions[numMatch] = permissions[i];
8233 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
8234 String[] permissions, int flags, int userId) {
8235 if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
8236 flags = updateFlagsForPackage(flags, userId);
8237 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8238 true /* requireFullPermission */, false /* checkShell */,
8239 "get packages holding permissions");
8240 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8243 synchronized (mLock) {
8244 ArrayList<PackageInfo> list = new ArrayList<>();
8245 boolean[] tmpBools = new boolean[permissions.length];
8246 if (listUninstalled) {
8247 for (PackageSetting ps : mSettings.mPackages.values()) {
8248 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8252 for (AndroidPackage pkg : mPackages.values()) {
8253 PackageSetting ps = getPackageSetting(pkg.getPackageName());
8255 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8261 return new ParceledListSlice<>(list);
8266 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
8267 final int callingUid = Binder.getCallingUid();
8268 return new ParceledListSlice<>(
8269 getInstalledApplicationsListInternal(flags, userId, callingUid));
8272 private List<ApplicationInfo> getInstalledApplicationsListInternal(int flags, int userId,
8274 if (getInstantAppPackageName(callingUid) != null) {
8275 return Collections.emptyList();
8277 if (!mUserManager.exists(userId)) return Collections.emptyList();
8278 flags = updateFlagsForApplication(flags, userId);
8279 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8281 mPermissionManager.enforceCrossUserPermission(
8284 false /* requireFullPermission */,
8285 false /* checkShell */,
8286 "get installed application info");
8289 synchronized (mLock) {
8290 ArrayList<ApplicationInfo> list;
8291 if (listUninstalled) {
8292 list = new ArrayList<>(mSettings.mPackages.size());
8293 for (PackageSetting ps : mSettings.mPackages.values()) {
8295 int effectiveFlags = flags;
8296 if (ps.isSystem()) {
8297 effectiveFlags |= PackageManager.MATCH_ANY_USER;
8299 if (ps.pkg != null) {
8300 if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8303 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
8306 ai = PackageInfoUtils.generateApplicationInfo(ps.pkg, effectiveFlags,
8307 ps.readUserState(userId), userId, ps);
8309 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
8312 // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
8313 // and already converts to externally visible package name
8314 ai = generateApplicationInfoFromSettingsLPw(ps.name,
8315 callingUid, effectiveFlags, userId);
8322 list = new ArrayList<>(mPackages.size());
8323 for (AndroidPackage p : mPackages.values()) {
8324 final PackageSetting ps = getPackageSetting(p.getPackageName());
8326 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
8329 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
8332 ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(p, flags,
8333 ps.readUserState(userId), userId, ps);
8335 ai.packageName = resolveExternalPackageNameLPr(p);
8347 public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
8348 if (HIDE_EPHEMERAL_APIS) {
8351 if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8352 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8353 "getEphemeralApplications");
8355 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8356 true /* requireFullPermission */, false /* checkShell */,
8357 "getEphemeralApplications");
8358 synchronized (mLock) {
8359 List<InstantAppInfo> instantApps = mInstantAppRegistry
8360 .getInstantAppsLPr(userId);
8361 if (instantApps != null) {
8362 return new ParceledListSlice<>(instantApps);
8369 public boolean isInstantApp(String packageName, int userId) {
8370 final int callingUid = Binder.getCallingUid();
8371 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
8372 true /* requireFullPermission */, false /* checkShell */,
8375 return isInstantAppInternal(packageName, userId, callingUid);
8378 private boolean isInstantAppInternal(String packageName, @UserIdInt int userId,
8380 if (HIDE_EPHEMERAL_APIS) {
8383 synchronized (mLock) {
8384 if (Process.isIsolated(callingUid)) {
8385 callingUid = mIsolatedOwners.get(callingUid);
8387 final PackageSetting ps = mSettings.mPackages.get(packageName);
8388 final boolean returnAllowed =
8390 && (isCallerSameApp(packageName, callingUid)
8391 || canViewInstantApps(callingUid, userId)
8392 || mInstantAppRegistry.isInstantAccessGranted(
8393 userId, UserHandle.getAppId(callingUid), ps.appId));
8394 if (returnAllowed) {
8395 return ps.getInstantApp(userId);
8402 public byte[] getInstantAppCookie(String packageName, int userId) {
8403 if (HIDE_EPHEMERAL_APIS) {
8407 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8408 true /* requireFullPermission */, false /* checkShell */,
8409 "getInstantAppCookie");
8410 if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8413 synchronized (mLock) {
8414 return mInstantAppRegistry.getInstantAppCookieLPw(
8415 packageName, userId);
8420 public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8421 if (HIDE_EPHEMERAL_APIS) {
8425 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8426 true /* requireFullPermission */, true /* checkShell */,
8427 "setInstantAppCookie");
8428 if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8431 synchronized (mLock) {
8432 return mInstantAppRegistry.setInstantAppCookieLPw(
8433 packageName, cookie, userId);
8438 public Bitmap getInstantAppIcon(String packageName, int userId) {
8439 if (HIDE_EPHEMERAL_APIS) {
8443 if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8444 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8445 "getInstantAppIcon");
8447 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8448 true /* requireFullPermission */, false /* checkShell */,
8449 "getInstantAppIcon");
8451 synchronized (mLock) {
8452 return mInstantAppRegistry.getInstantAppIconLPw(
8453 packageName, userId);
8457 private boolean isCallerSameApp(String packageName, int uid) {
8458 AndroidPackage pkg = mPackages.get(packageName);
8460 && UserHandle.getAppId(uid) == pkg.getUid();
8464 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8465 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8466 return ParceledListSlice.emptyList();
8468 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8471 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8472 final ArrayList<ApplicationInfo> finalList = new ArrayList<>();
8475 synchronized (mLock) {
8476 final Iterator<AndroidPackage> i = mPackages.values().iterator();
8477 final int userId = UserHandle.getCallingUserId();
8478 while (i.hasNext()) {
8479 final AndroidPackage p = i.next();
8481 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8482 && !p.isDirectBootAware();
8483 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8484 && p.isDirectBootAware();
8486 if (p.isPersistent()
8487 && (!mSafeMode || p.isSystem())
8488 && (matchesUnaware || matchesAware)) {
8489 PackageSetting ps = mSettings.mPackages.get(p.getPackageName());
8491 ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(p, flags,
8492 ps.readUserState(userId), userId, ps);
8505 public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8506 return resolveContentProviderInternal(name, flags, userId);
8509 private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
8510 if (!mUserManager.exists(userId)) return null;
8511 flags = updateFlagsForComponent(flags, userId);
8512 final int callingUid = Binder.getCallingUid();
8513 final ProviderInfo providerInfo = mComponentResolver.queryProvider(name, flags, userId);
8514 if (providerInfo == null) {
8517 if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
8520 synchronized (mLock) {
8521 final PackageSetting ps = mSettings.mPackages.get(providerInfo.packageName);
8522 final ComponentName component =
8523 new ComponentName(providerInfo.packageName, providerInfo.name);
8524 if (shouldFilterApplicationLocked(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8527 return providerInfo;
8535 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8536 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8539 mComponentResolver.querySyncProviders(
8540 outNames, outInfo, mSafeMode, UserHandle.getCallingUserId());
8544 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8545 int uid, int flags, String metaDataKey) {
8546 final int callingUid = Binder.getCallingUid();
8547 final int userId = processName != null ? UserHandle.getUserId(uid)
8548 : UserHandle.getCallingUserId();
8549 if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
8550 flags = updateFlagsForComponent(flags, userId);
8551 ArrayList<ProviderInfo> finalList = null;
8552 final List<ProviderInfo> matchList =
8553 mComponentResolver.queryProviders(processName, metaDataKey, uid, flags, userId);
8554 final int listSize = (matchList == null ? 0 : matchList.size());
8555 synchronized (mLock) {
8556 for (int i = 0; i < listSize; i++) {
8557 final ProviderInfo providerInfo = matchList.get(i);
8558 if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
8561 final PackageSetting ps = mSettings.mPackages.get(providerInfo.packageName);
8562 final ComponentName component =
8563 new ComponentName(providerInfo.packageName, providerInfo.name);
8564 if (shouldFilterApplicationLocked(
8565 ps, callingUid, component, TYPE_PROVIDER, userId)) {
8568 if (finalList == null) {
8569 finalList = new ArrayList<>(listSize - i);
8571 finalList.add(providerInfo);
8575 if (finalList != null) {
8576 finalList.sort(sProviderInitOrderSorter);
8577 return new ParceledListSlice<>(finalList);
8580 return ParceledListSlice.emptyList();
8584 public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8586 synchronized (mLock) {
8587 final int callingUid = Binder.getCallingUid();
8588 final int callingUserId = UserHandle.getUserId(callingUid);
8589 String packageName = component.getPackageName();
8590 final PackageSetting ps = mSettings.mPackages.get(packageName);
8591 AndroidPackage pkg = mPackages.get(packageName);
8592 if (ps == null || pkg == null) return null;
8593 if (shouldFilterApplicationLocked(
8594 ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8597 final ParsedInstrumentation i = mInstrumentation.get(component);
8598 return PackageInfoUtils.generateInstrumentationInfo(i, pkg, flags, callingUserId, ps);
8603 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8604 String targetPackage, int flags) {
8605 final int callingUid = Binder.getCallingUid();
8606 final int callingUserId = UserHandle.getUserId(callingUid);
8607 final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8608 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
8609 return ParceledListSlice.emptyList();
8611 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags,
8615 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8616 int flags, int userId) {
8617 ArrayList<InstrumentationInfo> finalList = new ArrayList<>();
8620 synchronized (mLock) {
8621 final Iterator<ParsedInstrumentation> i = mInstrumentation.values().iterator();
8622 while (i.hasNext()) {
8623 final ParsedInstrumentation p = i.next();
8624 if (targetPackage == null
8625 || targetPackage.equals(p.getTargetPackage())) {
8626 String packageName = p.getPackageName();
8627 AndroidPackage pkg = mPackages.get(packageName);
8628 PackageSetting pkgSetting = getPackageSetting(packageName);
8630 InstrumentationInfo ii = PackageInfoUtils.generateInstrumentationInfo(p,
8631 pkg, flags, userId, pkgSetting);
8643 private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags,
8644 long currentTime, PackageParser2 packageParser, ExecutorService executorService) {
8645 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
8647 scanDirLI(scanDir, parseFlags, scanFlags, currentTime, packageParser, executorService);
8649 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8653 private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime,
8654 PackageParser2 packageParser, ExecutorService executorService) {
8655 final File[] files = scanDir.listFiles();
8656 if (ArrayUtils.isEmpty(files)) {
8657 Log.d(TAG, "No files in app dir " + scanDir);
8661 if (DEBUG_PACKAGE_SCANNING) {
8662 Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
8663 + " flags=0x" + Integer.toHexString(parseFlags));
8666 ParallelPackageParser parallelPackageParser =
8667 new ParallelPackageParser(packageParser, executorService);
8669 // Submit files for parsing in parallel
8671 for (File file : files) {
8672 final boolean isPackage = (isApkFile(file) || file.isDirectory())
8673 && !PackageInstallerService.isStageName(file.getName());
8675 // Ignore entries which are not packages
8678 parallelPackageParser.submit(file, parseFlags);
8682 // Process results one by one
8683 for (; fileCount > 0; fileCount--) {
8684 ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8685 Throwable throwable = parseResult.throwable;
8686 int errorCode = PackageManager.INSTALL_SUCCEEDED;
8688 if (throwable == null) {
8689 // TODO(toddke): move lower in the scan chain
8690 // Static shared libraries have synthetic package names
8691 if (parseResult.parsedPackage.isStaticSharedLibrary()) {
8692 renameStaticSharedLibraryPackage(parseResult.parsedPackage);
8695 addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags,
8697 } catch (PackageManagerException e) {
8698 errorCode = e.error;
8699 Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8701 } else if (throwable instanceof PackageParserException) {
8702 PackageParserException e = (PackageParserException)
8704 errorCode = e.error;
8705 Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8707 throw new IllegalStateException("Unexpected exception occurred while parsing "
8708 + parseResult.scanFile, throwable);
8711 // Delete invalid userdata apps
8712 if ((scanFlags & SCAN_AS_SYSTEM) == 0
8713 && errorCode != PackageManager.INSTALL_SUCCEEDED) {
8714 logCriticalInfo(Log.WARN,
8715 "Deleting invalid package at " + parseResult.scanFile);
8716 removeCodePathLI(parseResult.scanFile);
8721 public static void reportSettingsProblem(int priority, String msg) {
8722 logCriticalInfo(priority, msg);
8725 private void collectCertificatesLI(PackageSetting ps, ParsedPackage parsedPackage,
8726 boolean forceCollect, boolean skipVerify) throws PackageManagerException {
8727 // When upgrading from pre-N MR1, verify the package time stamp using the package
8728 // directory and not the APK file.
8729 final long lastModifiedTime = mIsPreNMR1Upgrade
8730 ? new File(parsedPackage.getCodePath()).lastModified()
8731 : getLastModifiedTime(parsedPackage);
8732 final VersionInfo settingsVersionForPackage = getSettingsVersionForPackage(parsedPackage);
8733 if (ps != null && !forceCollect
8734 && ps.codePathString.equals(parsedPackage.getCodePath())
8735 && ps.timeStamp == lastModifiedTime
8736 && !isCompatSignatureUpdateNeeded(settingsVersionForPackage)
8737 && !isRecoverSignatureUpdateNeeded(settingsVersionForPackage)) {
8738 if (ps.signatures.mSigningDetails.signatures != null
8739 && ps.signatures.mSigningDetails.signatures.length != 0
8740 && ps.signatures.mSigningDetails.signatureSchemeVersion
8741 != SignatureSchemeVersion.UNKNOWN) {
8742 // Optimization: reuse the existing cached signing data
8743 // if the package appears to be unchanged.
8744 parsedPackage.setSigningDetails(
8745 new PackageParser.SigningDetails(ps.signatures.mSigningDetails));
8749 Slog.w(TAG, "PackageSetting for " + ps.name
8750 + " is missing signatures. Collecting certs again to recover them.");
8752 Slog.i(TAG, parsedPackage.getCodePath() + " changed; collecting certs" +
8753 (forceCollect ? " (forced)" : ""));
8757 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
8758 parsedPackage.setSigningDetails(
8759 ParsingPackageUtils.collectCertificates(parsedPackage, skipVerify));
8760 } catch (PackageParserException e) {
8761 throw PackageManagerException.from(e);
8763 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8768 * Clear the package profile if this was an upgrade and the package
8769 * version was updated.
8771 private void maybeClearProfilesForUpgradesLI(
8772 @Nullable PackageSetting originalPkgSetting,
8773 @NonNull AndroidPackage pkg) {
8774 if (originalPkgSetting == null || !isDeviceUpgrading()) {
8777 if (originalPkgSetting.versionCode == pkg.getVersionCode()) {
8781 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
8782 if (DEBUG_INSTALL) {
8783 Slog.d(TAG, originalPkgSetting.name
8784 + " clear profile due to version change "
8785 + originalPkgSetting.versionCode + " != "
8786 + pkg.getVersionCode());
8791 * Traces a package scan.
8792 * @see #scanPackageLI(File, int, int, long, UserHandle)
8794 @GuardedBy({"mInstallLock", "mLock"})
8795 private AndroidPackage scanPackageTracedLI(File scanFile, final int parseFlags,
8796 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8797 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
8799 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
8801 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8806 * Scans a package and returns the newly parsed package.
8807 * Returns {@code null} in case of errors and the error code is stored in mLastScanError
8809 @GuardedBy({"mInstallLock", "mLock"})
8810 private AndroidPackage scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8811 long currentTime, UserHandle user) throws PackageManagerException {
8812 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8813 PackageParser2 pp = new PackageParser2(mSeparateProcesses, mOnlyCore, mMetrics, null,
8814 mPackageParserCallback);
8816 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8817 final ParsedPackage parsedPackage;
8819 parsedPackage = pp.parsePackage(scanFile, parseFlags, false);
8820 } catch (PackageParserException e) {
8821 throw PackageManagerException.from(e);
8823 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8826 // Static shared libraries have synthetic package names
8827 if (parsedPackage.isStaticSharedLibrary()) {
8828 renameStaticSharedLibraryPackage(parsedPackage);
8831 return addForInitLI(parsedPackage, parseFlags, scanFlags, currentTime, user);
8835 * Returns if forced apk verification can be skipped for the whole package, including splits.
8837 private boolean canSkipForcedPackageVerification(AndroidPackage pkg) {
8838 if (!canSkipForcedApkVerification(pkg.getBaseCodePath())) {
8841 // TODO: Allow base and splits to be verified individually.
8842 String[] splitCodePaths = pkg.getSplitCodePaths();
8843 if (!ArrayUtils.isEmpty(splitCodePaths)) {
8844 for (int i = 0; i < splitCodePaths.length; i++) {
8845 if (!canSkipForcedApkVerification(splitCodePaths[i])) {
8854 * Returns if forced apk verification can be skipped, depending on current FSVerity setup and
8855 * whether the apk contains signed root hash. Note that the signer's certificate still needs to
8856 * match one in a trusted source, and should be done separately.
8858 private boolean canSkipForcedApkVerification(String apkPath) {
8859 if (!PackageManagerServiceUtils.isLegacyApkVerityEnabled()) {
8860 return VerityUtils.hasFsverity(apkPath);
8864 final byte[] rootHashObserved = VerityUtils.generateApkVerityRootHash(apkPath);
8865 if (rootHashObserved == null) {
8866 return false; // APK does not contain Merkle tree root hash.
8868 synchronized (mInstallLock) {
8869 // Returns whether the observed root hash matches what kernel has.
8870 mInstaller.assertFsverityRootHashMatches(apkPath, rootHashObserved);
8873 } catch (InstallerException | IOException | DigestException |
8874 NoSuchAlgorithmException e) {
8875 Slog.w(TAG, "Error in fsverity check. Fallback to full apk verification.", e);
8881 * Adds a new package to the internal data structures during platform initialization.
8882 * <p>After adding, the package is known to the system and available for querying.
8883 * <p>For packages located on the device ROM [eg. packages located in /system, /vendor,
8884 * etc...], additional checks are performed. Basic verification [such as ensuring
8885 * matching signatures, checking version codes, etc...] occurs if the package is
8886 * identical to a previously known package. If the package fails a signature check,
8887 * the version installed on /data will be removed. If the version of the new package
8888 * is less than or equal than the version on /data, it will be ignored.
8889 * <p>Regardless of the package location, the results are applied to the internal
8890 * structures and the package is made available to the rest of the system.
8891 * <p>NOTE: The return value should be removed. It's the passed in package object.
8893 @GuardedBy({"mInstallLock", "mLock"})
8894 private AndroidPackage addForInitLI(ParsedPackage parsedPackage,
8895 @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8896 @Nullable UserHandle user)
8897 throws PackageManagerException {
8898 final boolean scanSystemPartition = (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0;
8899 final String renamedPkgName;
8900 final PackageSetting disabledPkgSetting;
8901 final boolean isSystemPkgUpdated;
8902 final boolean pkgAlreadyExists;
8903 PackageSetting pkgSetting;
8905 synchronized (mLock) {
8906 renamedPkgName = mSettings.getRenamedPackageLPr(parsedPackage.getRealPackage());
8907 final String realPkgName = getRealPackageName(parsedPackage, renamedPkgName);
8908 if (realPkgName != null) {
8909 ensurePackageRenamed(parsedPackage, renamedPkgName);
8911 final PackageSetting originalPkgSetting = getOriginalPackageLocked(parsedPackage,
8913 final PackageSetting installedPkgSetting = mSettings.getPackageLPr(
8914 parsedPackage.getPackageName());
8915 pkgSetting = originalPkgSetting == null ? installedPkgSetting : originalPkgSetting;
8916 pkgAlreadyExists = pkgSetting != null;
8917 final String disabledPkgName = pkgAlreadyExists
8918 ? pkgSetting.name : parsedPackage.getPackageName();
8919 if (scanSystemPartition && !pkgAlreadyExists
8920 && mSettings.getDisabledSystemPkgLPr(disabledPkgName) != null) {
8921 // The updated-package data for /system apk remains inconsistently
8922 // after the package data for /data apk is lost accidentally.
8923 // To recover it, enable /system apk and install it as non-updated system app.
8924 Slog.w(TAG, "Inconsistent package setting of updated system app for "
8925 + disabledPkgName + ". To recover it, enable the system app"
8926 + "and install it as non-updated system app.");
8927 mSettings.removeDisabledSystemPackageLPw(disabledPkgName);
8929 disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(disabledPkgName);
8930 isSystemPkgUpdated = disabledPkgSetting != null;
8932 if (DEBUG_INSTALL && isSystemPkgUpdated) {
8933 Slog.d(TAG, "updatedPkg = " + disabledPkgSetting);
8936 final SharedUserSetting sharedUserSetting = (parsedPackage.getSharedUserId() != null)
8937 ? mSettings.getSharedUserLPw(parsedPackage.getSharedUserId(),
8938 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true)
8940 if (DEBUG_PACKAGE_SCANNING
8941 && (parseFlags & PackageParser.PARSE_CHATTY) != 0
8942 && sharedUserSetting != null) {
8943 Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId()
8944 + " (uid=" + sharedUserSetting.userId + "):"
8945 + " packages=" + sharedUserSetting.packages);
8948 if (scanSystemPartition) {
8949 if (isSystemPkgUpdated) {
8950 // we're updating the disabled package, so, scan it as the package setting
8951 boolean isPlatformPackage = mPlatformPackage != null
8952 && Objects.equals(mPlatformPackage.getPackageName(),
8953 parsedPackage.getPackageName());
8954 final ScanRequest request = new ScanRequest(parsedPackage, sharedUserSetting,
8955 null, disabledPkgSetting /* pkgSetting */,
8956 null /* disabledPkgSetting */, null /* originalPkgSetting */,
8957 null, parseFlags, scanFlags, isPlatformPackage, user, null);
8958 applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, true);
8959 final ScanResult scanResult =
8960 scanPackageOnlyLI(request, mInjector, mFactoryTest, -1L);
8961 if (scanResult.existingSettingCopied && scanResult.request.pkgSetting != null) {
8962 scanResult.request.pkgSetting.updateFrom(scanResult.pkgSetting);
8968 final boolean newPkgChangedPaths =
8969 pkgAlreadyExists && !pkgSetting.codePathString.equals(parsedPackage.getCodePath());
8970 final boolean newPkgVersionGreater =
8971 pkgAlreadyExists && parsedPackage.getLongVersionCode() > pkgSetting.versionCode;
8972 final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
8973 && newPkgChangedPaths && newPkgVersionGreater;
8974 if (isSystemPkgBetter) {
8975 // The version of the application on /system is greater than the version on
8976 // /data. Switch back to the application on /system.
8977 // It's safe to assume the application on /system will correctly scan. If not,
8978 // there won't be a working copy of the application.
8979 synchronized (mLock) {
8980 // just remove the loaded entries from package lists
8981 mPackages.remove(pkgSetting.name);
8984 logCriticalInfo(Log.WARN,
8985 "System package updated;"
8986 + " name: " + pkgSetting.name
8987 + "; " + pkgSetting.versionCode + " --> " + parsedPackage.getLongVersionCode()
8988 + "; " + pkgSetting.codePathString + " --> " + parsedPackage.getCodePath());
8990 final InstallArgs args = createInstallArgsForExisting(
8991 pkgSetting.codePathString,
8992 pkgSetting.resourcePathString, getAppDexInstructionSets(
8993 pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString));
8994 args.cleanUpResourcesLI();
8995 synchronized (mLock) {
8996 mSettings.enableSystemPackageLPw(pkgSetting.name);
9000 if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {
9001 // The version of the application on the /system partition is less than or
9002 // equal to the version on the /data partition. Throw an exception and use
9003 // the application already installed on the /data partition.
9004 throw new PackageManagerException(Log.WARN, "Package " + parsedPackage.getPackageName()
9005 + " at " + parsedPackage.getCodePath() + " ignored: updated version "
9006 + pkgSetting.versionCode + " better than this "
9007 + parsedPackage.getLongVersionCode());
9010 // Verify certificates against what was last scanned. Force re-collecting certificate in two
9012 // 1) when scanning system, force re-collect only if system is upgrading.
9013 // 2) when scannning /data, force re-collect only if the app is privileged (updated from
9014 // preinstall, or treated as privileged, e.g. due to shared user ID).
9015 final boolean forceCollect = scanSystemPartition ? mIsUpgrade
9016 : PackageManagerServiceUtils.isApkVerificationForced(pkgSetting);
9017 if (DEBUG_VERIFY && forceCollect) {
9018 Slog.d(TAG, "Force collect certificate of " + parsedPackage.getPackageName());
9021 // Full APK verification can be skipped during certificate collection, only if the file is
9022 // in verified partition, or can be verified on access (when apk verity is enabled). In both
9023 // cases, only data in Signing Block is verified instead of the whole file.
9024 // TODO(b/136132412): skip for Incremental installation
9025 final boolean skipVerify = scanSystemPartition
9026 || (forceCollect && canSkipForcedPackageVerification(parsedPackage));
9027 collectCertificatesLI(pkgSetting, parsedPackage, forceCollect, skipVerify);
9029 // Reset profile if the application version is changed
9030 maybeClearProfilesForUpgradesLI(pkgSetting, parsedPackage);
9033 * A new system app appeared, but we already had a non-system one of the
9034 * same name installed earlier.
9036 boolean shouldHideSystemApp = false;
9037 // A new application appeared on /system, but, we already have a copy of
9038 // the application installed on /data.
9039 if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists
9040 && !pkgSetting.isSystem()) {
9042 if (!parsedPackage.getSigningDetails()
9043 .checkCapability(pkgSetting.signatures.mSigningDetails,
9044 PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)
9045 && !pkgSetting.signatures.mSigningDetails.checkCapability(
9046 parsedPackage.getSigningDetails(),
9047 PackageParser.SigningDetails.CertCapabilities.ROLLBACK)) {
9048 logCriticalInfo(Log.WARN,
9049 "System package signature mismatch;"
9050 + " name: " + pkgSetting.name);
9051 try (@SuppressWarnings("unused") PackageFreezer freezer = freezePackage(
9052 parsedPackage.getPackageName(),
9053 "scanPackageInternalLI")) {
9054 deletePackageLIF(parsedPackage.getPackageName(), null, true, null, 0, null,
9058 } else if (newPkgVersionGreater) {
9059 // The application on /system is newer than the application on /data.
9060 // Simply remove the application on /data [keeping application data]
9061 // and replace it with the version on /system.
9062 logCriticalInfo(Log.WARN,
9063 "System package enabled;"
9064 + " name: " + pkgSetting.name
9065 + "; " + pkgSetting.versionCode + " --> "
9066 + parsedPackage.getLongVersionCode()
9067 + "; " + pkgSetting.codePathString + " --> "
9068 + parsedPackage.getCodePath());
9069 InstallArgs args = createInstallArgsForExisting(
9070 pkgSetting.codePathString,
9071 pkgSetting.resourcePathString, getAppDexInstructionSets(
9072 pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString));
9073 synchronized (mInstallLock) {
9074 args.cleanUpResourcesLI();
9077 // The application on /system is older than the application on /data. Hide
9078 // the application on /system and the version on /data will be scanned later
9079 // and re-added like an update.
9080 shouldHideSystemApp = true;
9081 logCriticalInfo(Log.INFO,
9082 "System package disabled;"
9083 + " name: " + pkgSetting.name
9084 + "; old: " + pkgSetting.codePathString + " @ "
9085 + pkgSetting.versionCode
9086 + "; new: " + parsedPackage.getCodePath() + " @ "
9087 + parsedPackage.getCodePath());
9091 final ScanResult scanResult = scanPackageNewLI(parsedPackage, parseFlags, scanFlags
9092 | SCAN_UPDATE_SIGNATURE, currentTime, user, null);
9093 if (scanResult.success) {
9094 synchronized (mLock) {
9095 boolean appIdCreated = false;
9097 final String pkgName = scanResult.pkgSetting.name;
9098 final Map<String, ReconciledPackage> reconcileResult = reconcilePackagesLocked(
9099 new ReconcileRequest(
9100 Collections.singletonMap(pkgName, scanResult),
9103 Collections.singletonMap(
9104 pkgName, getSettingsVersionForPackage(parsedPackage)),
9105 Collections.singletonMap(pkgName,
9106 getSharedLibLatestVersionSetting(scanResult))),
9107 mSettings.mKeySetManagerService);
9108 appIdCreated = optimisticallyRegisterAppId(scanResult);
9109 commitReconciledScanResultLocked(reconcileResult.get(pkgName));
9110 } catch (PackageManagerException e) {
9112 cleanUpAppIdCreation(scanResult);
9119 if (shouldHideSystemApp) {
9120 synchronized (mLock) {
9121 mSettings.disableSystemPackageLPw(parsedPackage.getPackageName(), true);
9124 return scanResult.pkgSetting.pkg;
9127 // TODO:(b/135203078): Move to parsing
9128 private static void renameStaticSharedLibraryPackage(ParsedPackage parsedPackage) {
9129 // Derive the new package synthetic package name
9130 parsedPackage.setPackageName(parsedPackage.getPackageName() + STATIC_SHARED_LIB_DELIMITER
9131 + parsedPackage.getStaticSharedLibVersion());
9134 static String fixProcessName(String defProcessName, String processName) {
9135 if (processName == null) {
9136 return defProcessName;
9142 * Enforces that only the system UID or root's UID can call a method exposed
9145 * @param message used as message if SecurityException is thrown
9146 * @throws SecurityException if the caller is not system or root
9148 private static void enforceSystemOrRoot(String message) {
9149 final int uid = Binder.getCallingUid();
9150 if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
9151 throw new SecurityException(message);
9156 * Enforces that only the system UID or root's UID or shell's UID can call
9157 * a method exposed via Binder.
9159 * @param message used as message if SecurityException is thrown
9160 * @throws SecurityException if the caller is not system or shell
9162 private static void enforceSystemOrRootOrShell(String message) {
9163 final int uid = Binder.getCallingUid();
9164 if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID && uid != Process.SHELL_UID) {
9165 throw new SecurityException(message);
9170 public void performFstrimIfNeeded() {
9171 enforceSystemOrRoot("Only the system can request fstrim");
9173 // Before everything else, see whether we need to fstrim.
9175 IStorageManager sm = PackageHelper.getStorageManager();
9177 boolean doTrim = false;
9178 final long interval = android.provider.Settings.Global.getLong(
9179 mContext.getContentResolver(),
9180 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
9181 DEFAULT_MANDATORY_FSTRIM_INTERVAL);
9183 final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
9184 if (timeSinceLast > interval) {
9186 Slog.w(TAG, "No disk maintenance in " + timeSinceLast
9187 + "; running immediately");
9191 final boolean dexOptDialogShown;
9192 synchronized (mLock) {
9193 dexOptDialogShown = mDexOptDialogShown;
9195 if (!isFirstBoot() && dexOptDialogShown) {
9197 ActivityManager.getService().showBootMessage(
9198 mContext.getResources().getString(
9199 R.string.android_upgrading_fstrim), true);
9200 } catch (RemoteException e) {
9203 sm.runMaintenance();
9206 Slog.e(TAG, "storageManager service unavailable!");
9208 } catch (RemoteException e) {
9209 // Can't happen; StorageManagerService is local
9214 public void updatePackagesIfNeeded() {
9215 enforceSystemOrRoot("Only the system can request package update");
9217 // We need to re-extract after an OTA.
9218 boolean causeUpgrade = isDeviceUpgrading();
9220 // First boot or factory reset.
9221 // Note: we also handle devices that are upgrading to N right now as if it is their
9222 // first boot, as they do not have profile data.
9223 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
9225 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
9226 boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
9228 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
9232 List<PackageSetting> pkgSettings;
9233 synchronized (mLock) {
9234 pkgSettings = PackageManagerServiceUtils.getPackagesForDexopt(
9235 mSettings.mPackages.values(), this);
9238 List<AndroidPackage> pkgs = new ArrayList<>(pkgSettings.size());
9239 for (int index = 0; index < pkgSettings.size(); index++) {
9240 pkgs.add(pkgSettings.get(index).pkg);
9243 final long startTime = System.nanoTime();
9244 final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
9245 causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
9246 false /* bootComplete */);
9248 final int elapsedTimeSeconds =
9249 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
9251 MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
9252 MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
9253 MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
9254 MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
9255 MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
9259 * Return the prebuilt profile path given a package base code path.
9261 private static String getPrebuildProfilePath(AndroidPackage pkg) {
9262 return pkg.getBaseCodePath() + ".prof";
9266 * Performs dexopt on the set of packages in {@code packages} and returns an int array
9267 * containing statistics about the invocation. The array consists of three elements,
9268 * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
9269 * and {@code numberOfPackagesFailed}.
9271 private int[] performDexOptUpgrade(List<AndroidPackage> pkgs, boolean showDialog,
9272 final int compilationReason, boolean bootComplete) {
9274 int numberOfPackagesVisited = 0;
9275 int numberOfPackagesOptimized = 0;
9276 int numberOfPackagesSkipped = 0;
9277 int numberOfPackagesFailed = 0;
9278 final int numberOfPackagesToDexopt = pkgs.size();
9280 for (AndroidPackage pkg : pkgs) {
9281 numberOfPackagesVisited++;
9283 boolean useProfileForDexopt = false;
9285 if ((isFirstBoot() || isDeviceUpgrading()) && pkg.isSystem()) {
9286 // Copy over initial preopt profiles since we won't get any JIT samples for methods
9287 // that are already compiled.
9288 File profileFile = new File(getPrebuildProfilePath(pkg));
9289 // Copy profile if it exists.
9290 if (profileFile.exists()) {
9292 // We could also do this lazily before calling dexopt in
9293 // PackageDexOptimizer to prevent this happening on first boot. The issue
9294 // is that we don't have a good way to say "do this only once".
9295 if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9296 pkg.getUid(), pkg.getPackageName(),
9297 ArtManager.getProfileName(null))) {
9298 Log.e(TAG, "Installer failed to copy system profile!");
9300 // Disabled as this causes speed-profile compilation during first boot
9301 // even if things are already compiled.
9302 // useProfileForDexopt = true;
9304 } catch (Exception e) {
9305 Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
9309 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(
9310 pkg.getPackageName());
9311 // Handle compressed APKs in this path. Only do this for stubs with profiles to
9312 // minimize the number off apps being speed-profile compiled during first boot.
9313 // The other paths will not change the filter.
9314 if (disabledPs != null && disabledPs.pkg.isStub()) {
9315 // The package is the stub one, remove the stub suffix to get the normal
9316 // package and APK names.
9317 String systemProfilePath =
9318 getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
9319 profileFile = new File(systemProfilePath);
9320 // If we have a profile for a compressed APK, copy it to the reference
9322 // Note that copying the profile here will cause it to override the
9323 // reference profile every OTA even though the existing reference profile
9324 // may have more data. We can't copy during decompression since the
9325 // directories are not set up at that point.
9326 if (profileFile.exists()) {
9328 // We could also do this lazily before calling dexopt in
9329 // PackageDexOptimizer to prevent this happening on first boot. The
9330 // issue is that we don't have a good way to say "do this only
9332 if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9333 pkg.getUid(), pkg.getPackageName(),
9334 ArtManager.getProfileName(null))) {
9335 Log.e(TAG, "Failed to copy system profile for stub package!");
9337 useProfileForDexopt = true;
9339 } catch (Exception e) {
9340 Log.e(TAG, "Failed to copy profile " +
9341 profileFile.getAbsolutePath() + " ", e);
9348 if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
9350 Log.i(TAG, "Skipping update of non-optimizable app " + pkg.getPackageName());
9352 numberOfPackagesSkipped++;
9357 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
9358 numberOfPackagesToDexopt + ": " + pkg.getPackageName());
9363 ActivityManager.getService().showBootMessage(
9364 mContext.getResources().getString(R.string.android_upgrading_apk,
9365 numberOfPackagesVisited, numberOfPackagesToDexopt), true);
9366 } catch (RemoteException e) {
9368 synchronized (mLock) {
9369 mDexOptDialogShown = true;
9373 int pkgCompilationReason = compilationReason;
9374 if (useProfileForDexopt) {
9375 // Use background dexopt mode to try and use the profile. Note that this does not
9376 // guarantee usage of the profile.
9377 pkgCompilationReason = PackageManagerService.REASON_BACKGROUND_DEXOPT;
9380 if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
9381 mArtManagerService.compileLayouts(pkg);
9384 // checkProfiles is false to avoid merging profiles during boot which
9385 // might interfere with background compilation (b/28612421).
9386 // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
9387 // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
9388 // trade-off worth doing to save boot time work.
9389 int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
9390 if (compilationReason == REASON_FIRST_BOOT) {
9391 // TODO: This doesn't cover the upgrade case, we should check for this too.
9392 dexoptFlags |= DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE;
9394 int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
9395 pkg.getPackageName(),
9396 pkgCompilationReason,
9399 switch (primaryDexOptStaus) {
9400 case PackageDexOptimizer.DEX_OPT_PERFORMED:
9401 numberOfPackagesOptimized++;
9403 case PackageDexOptimizer.DEX_OPT_SKIPPED:
9404 numberOfPackagesSkipped++;
9406 case PackageDexOptimizer.DEX_OPT_FAILED:
9407 numberOfPackagesFailed++;
9410 Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
9415 return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9416 numberOfPackagesFailed };
9420 public void notifyPackageUse(String packageName, int reason) {
9421 synchronized (mLock) {
9422 final int callingUid = Binder.getCallingUid();
9423 final int callingUserId = UserHandle.getUserId(callingUid);
9424 if (getInstantAppPackageName(callingUid) != null) {
9425 if (!isCallerSameApp(packageName, callingUid)) {
9429 if (isInstantApp(packageName, callingUserId)) {
9433 notifyPackageUseLocked(packageName, reason);
9438 private void notifyPackageUseLocked(String packageName, int reason) {
9439 final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
9440 if (pkgSetting == null) {
9443 pkgSetting.getPkgState().setLastPackageUsageTimeInMills(reason, System.currentTimeMillis());
9447 public void notifyDexLoad(String loadingPackageName, Map<String, String> classLoaderContextMap,
9449 int userId = UserHandle.getCallingUserId();
9450 ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
9452 Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
9453 + loadingPackageName + ", user=" + userId);
9456 mDexManager.notifyDexLoad(ai, classLoaderContextMap, loaderIsa, userId);
9460 public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
9461 IDexModuleRegisterCallback callback) {
9462 int userId = UserHandle.getCallingUserId();
9463 ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
9464 DexManager.RegisterDexModuleResult result;
9466 Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
9467 " calling user. package=" + packageName + ", user=" + userId);
9468 result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
9470 result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
9473 if (callback != null) {
9474 mHandler.post(() -> {
9476 callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
9477 } catch (RemoteException e) {
9478 Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
9485 * Ask the package manager to perform a dex-opt with the given compiler filter.
9487 * Note: exposed only for the shell command to allow moving packages explicitly to a
9491 public boolean performDexOptMode(String packageName,
9492 boolean checkProfiles, String targetCompilerFilter, boolean force,
9493 boolean bootComplete, String splitName) {
9494 int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
9495 (force ? DexoptOptions.DEXOPT_FORCE : 0) |
9496 (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
9497 return performDexOpt(new DexoptOptions(packageName, REASON_UNKNOWN,
9498 targetCompilerFilter, splitName, flags));
9502 * Ask the package manager to perform a dex-opt with the given compiler filter on the
9503 * secondary dex files belonging to the given package.
9505 * Note: exposed only for the shell command to allow moving packages explicitly to a
9509 public boolean performDexOptSecondary(String packageName, String compilerFilter,
9511 int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
9512 DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
9513 DexoptOptions.DEXOPT_BOOT_COMPLETE |
9514 (force ? DexoptOptions.DEXOPT_FORCE : 0);
9515 return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
9519 * Ask the package manager to compile layouts in the given package.
9522 public boolean compileLayouts(String packageName) {
9524 synchronized (mLock) {
9525 pkg = mPackages.get(packageName);
9530 return mViewCompiler.compileLayouts(pkg);
9533 /*package*/ boolean performDexOpt(DexoptOptions options) {
9534 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9536 } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
9540 if (options.isDexoptOnlySecondaryDex()) {
9541 return mDexManager.dexoptSecondaryDex(options);
9543 int dexoptStatus = performDexOptWithStatus(options);
9544 return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9549 * Perform dexopt on the given package and return one of following result:
9550 * {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
9551 * {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
9552 * {@link PackageDexOptimizer#DEX_OPT_FAILED}
9554 /* package */ int performDexOptWithStatus(DexoptOptions options) {
9555 return performDexOptTraced(options);
9558 private int performDexOptTraced(DexoptOptions options) {
9559 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9561 return performDexOptInternal(options);
9563 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9567 // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9568 // if the package can now be considered up to date for the given filter.
9569 private int performDexOptInternal(DexoptOptions options) {
9571 PackageSetting pkgSetting;
9572 synchronized (mLock) {
9573 p = mPackages.get(options.getPackageName());
9574 pkgSetting = mSettings.getPackageLPr(options.getPackageName());
9575 if (p == null || pkgSetting == null) {
9576 // Package could not be found. Report failure.
9577 return PackageDexOptimizer.DEX_OPT_FAILED;
9579 mPackageUsage.maybeWriteAsync(mSettings.mPackages);
9580 mCompilerStats.maybeWriteAsync();
9582 long callingId = Binder.clearCallingIdentity();
9584 synchronized (mInstallLock) {
9585 return performDexOptInternalWithDependenciesLI(p, pkgSetting, options);
9588 Binder.restoreCallingIdentity(callingId);
9592 public ArraySet<String> getOptimizablePackages() {
9593 ArraySet<String> pkgs = new ArraySet<>();
9594 synchronized (mLock) {
9595 for (AndroidPackage p : mPackages.values()) {
9596 if (PackageDexOptimizer.canOptimizePackage(p)) {
9597 pkgs.add(p.getPackageName());
9604 private int performDexOptInternalWithDependenciesLI(AndroidPackage p,
9605 @NonNull PackageSetting pkgSetting, DexoptOptions options) {
9606 // Select the dex optimizer based on the force parameter.
9607 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9608 // allocate an object here.
9609 PackageDexOptimizer pdo = options.isForce()
9610 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9611 : mPackageDexOptimizer;
9613 // Dexopt all dependencies first. Note: we ignore the return value and march on
9615 // Note that we are going to call performDexOpt on those libraries as many times as
9616 // they are referenced in packages. When we do a batch of performDexOpt (for example
9617 // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9618 // and the first package that uses the library will dexopt it. The
9619 // others will see that the compiled code for the library is up to date.
9620 Collection<SharedLibraryInfo> deps = findSharedLibraries(pkgSetting);
9621 final String[] instructionSets = getAppDexInstructionSets(
9622 AndroidPackageUtils.getPrimaryCpuAbi(p, pkgSetting),
9623 AndroidPackageUtils.getSecondaryCpuAbi(p, pkgSetting));
9624 if (!deps.isEmpty()) {
9625 DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
9626 options.getCompilationReason(), options.getCompilerFilter(),
9627 options.getSplitName(),
9628 options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
9629 for (SharedLibraryInfo info : deps) {
9630 AndroidPackage depPackage = null;
9631 PackageSetting depPackageSetting = null;
9632 synchronized (mLock) {
9633 depPackage = mPackages.get(info.getPackageName());
9634 depPackageSetting = mSettings.getPackageLPr(info.getPackageName());
9636 if (depPackage != null && depPackageSetting != null) {
9637 // TODO: Analyze and investigate if we (should) profile libraries.
9638 pdo.performDexOpt(depPackage, depPackageSetting, instructionSets,
9639 getOrCreateCompilerPackageStats(depPackage),
9640 mDexManager.getPackageUseInfoOrDefault(depPackage.getPackageName()),
9643 // TODO(ngeoffray): Support dexopting system shared libraries.
9648 return pdo.performDexOpt(p, pkgSetting, instructionSets,
9649 getOrCreateCompilerPackageStats(p),
9650 mDexManager.getPackageUseInfoOrDefault(p.getPackageName()), options);
9654 * Reconcile the information we have about the secondary dex files belonging to
9655 * {@code packageName} and the actual dex files. For all dex files that were
9656 * deleted, update the internal records and delete the generated oat files.
9659 public void reconcileSecondaryDexFiles(String packageName) {
9660 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9662 } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9665 mDexManager.reconcileSecondaryDexFiles(packageName);
9668 // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9669 // a reference there.
9670 /*package*/ DexManager getDexManager() {
9675 * Execute the background dexopt job immediately.
9678 public boolean runBackgroundDexoptJob(@Nullable List<String> packageNames) {
9679 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9682 enforceSystemOrRootOrShell("runBackgroundDexoptJob");
9683 final long identity = Binder.clearCallingIdentity();
9685 return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
9687 Binder.restoreCallingIdentity(identity);
9691 private static List<SharedLibraryInfo> findSharedLibraries(PackageSetting pkgSetting) {
9692 if (!pkgSetting.getPkgState().getUsesLibraryInfos().isEmpty()) {
9693 ArrayList<SharedLibraryInfo> retValue = new ArrayList<>();
9694 Set<String> collectedNames = new HashSet<>();
9695 for (SharedLibraryInfo info : pkgSetting.getPkgState().getUsesLibraryInfos()) {
9696 findSharedLibrariesRecursive(info, retValue, collectedNames);
9700 return Collections.emptyList();
9704 private static void findSharedLibrariesRecursive(SharedLibraryInfo info,
9705 ArrayList<SharedLibraryInfo> collected, Set<String> collectedNames) {
9706 if (!collectedNames.contains(info.getName())) {
9707 collectedNames.add(info.getName());
9708 collected.add(info);
9710 if (info.getDependencies() != null) {
9711 for (SharedLibraryInfo dep : info.getDependencies()) {
9712 findSharedLibrariesRecursive(dep, collected, collectedNames);
9718 List<PackageSetting> findSharedNonSystemLibraries(PackageSetting pkgSetting) {
9719 List<SharedLibraryInfo> deps = findSharedLibraries(pkgSetting);
9720 if (!deps.isEmpty()) {
9721 List<PackageSetting> retValue = new ArrayList<>();
9722 synchronized (mLock) {
9723 for (SharedLibraryInfo info : deps) {
9724 PackageSetting depPackageSetting =
9725 mSettings.getPackageLPr(info.getPackageName());
9726 if (depPackageSetting != null && depPackageSetting.pkg != null) {
9727 retValue.add(depPackageSetting);
9733 return Collections.emptyList();
9738 private SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version) {
9739 return getSharedLibraryInfo(name, version, mSharedLibraries, null);
9743 private static SharedLibraryInfo getSharedLibraryInfo(String name, long version,
9744 Map<String, LongSparseArray<SharedLibraryInfo>> existingLibraries,
9745 @Nullable Map<String, LongSparseArray<SharedLibraryInfo>> newLibraries) {
9746 if (newLibraries != null) {
9747 final LongSparseArray<SharedLibraryInfo> versionedLib = newLibraries.get(name);
9748 SharedLibraryInfo info = null;
9749 if (versionedLib != null) {
9750 info = versionedLib.get(version);
9756 final LongSparseArray<SharedLibraryInfo> versionedLib = existingLibraries.get(name);
9757 if (versionedLib == null) {
9760 return versionedLib.get(version);
9763 private SharedLibraryInfo getLatestSharedLibraVersionLPr(AndroidPackage pkg) {
9764 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(
9765 pkg.getStaticSharedLibName());
9766 if (versionedLib == null) {
9769 long previousLibVersion = -1;
9770 final int versionCount = versionedLib.size();
9771 for (int i = 0; i < versionCount; i++) {
9772 final long libVersion = versionedLib.keyAt(i);
9773 if (libVersion < pkg.getStaticSharedLibVersion()) {
9774 previousLibVersion = Math.max(previousLibVersion, libVersion);
9777 if (previousLibVersion >= 0) {
9778 return versionedLib.get(previousLibVersion);
9785 private PackageSetting getSharedLibLatestVersionSetting(@NonNull ScanResult scanResult) {
9786 PackageSetting sharedLibPackage = null;
9787 synchronized (mLock) {
9788 final SharedLibraryInfo latestSharedLibraVersionLPr =
9789 getLatestSharedLibraVersionLPr(scanResult.request.parsedPackage);
9790 if (latestSharedLibraVersionLPr != null) {
9791 sharedLibPackage = mSettings.getPackageLPr(
9792 latestSharedLibraVersionLPr.getPackageName());
9795 return sharedLibPackage;
9798 public void shutdown() {
9799 mPackageUsage.writeNow(mSettings.mPackages);
9800 mCompilerStats.writeNow();
9801 mDexManager.writePackageDexUsageNow();
9802 PackageWatchdog.getInstance(mContext).writeNow();
9804 // This is the last chance to write out pending restriction settings
9805 synchronized (mLock) {
9806 if (mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
9807 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
9808 for (int userId : mDirtyUsers) {
9809 mSettings.writePackageRestrictionsLPr(userId);
9811 mDirtyUsers.clear();
9817 public void dumpProfiles(String packageName) {
9819 synchronized (mLock) {
9820 pkg = mPackages.get(packageName);
9822 throw new IllegalArgumentException("Unknown package: " + packageName);
9825 /* Only the shell, root, or the app user should be able to dump profiles. */
9826 int callingUid = Binder.getCallingUid();
9827 if (callingUid != Process.SHELL_UID &&
9828 callingUid != Process.ROOT_UID &&
9829 callingUid != pkg.getUid()) {
9830 throw new SecurityException("dumpProfiles");
9833 synchronized (mInstallLock) {
9834 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
9835 mArtManagerService.dumpProfiles(pkg);
9836 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9841 public void forceDexOpt(String packageName) {
9842 enforceSystemOrRoot("forceDexOpt");
9845 PackageSetting pkgSetting;
9846 synchronized (mLock) {
9847 pkg = mPackages.get(packageName);
9848 pkgSetting = mSettings.getPackageLPr(packageName);
9849 if (pkg == null || pkgSetting == null) {
9850 throw new IllegalArgumentException("Unknown package: " + packageName);
9854 synchronized (mInstallLock) {
9855 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9857 // Whoever is calling forceDexOpt wants a compiled package.
9858 // Don't use profiles since that may cause compilation to be skipped.
9859 final int res = performDexOptInternalWithDependenciesLI(pkg, pkgSetting,
9860 new DexoptOptions(packageName,
9861 getDefaultCompilerFilter(),
9862 DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
9864 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9865 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
9866 throw new IllegalStateException("Failed to dexopt: " + res);
9872 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, AndroidPackage newPkg) {
9873 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9874 Slog.w(TAG, "Unable to update from " + oldPkg.name
9875 + " to " + newPkg.getPackageName()
9876 + ": old package not in system partition");
9878 } else if (mPackages.get(oldPkg.name) != null) {
9879 Slog.w(TAG, "Unable to update from " + oldPkg.name
9880 + " to " + newPkg.getPackageName()
9881 + ": old package still exists");
9887 @GuardedBy("mInstallLock")
9888 void removeCodePathLI(File codePath) {
9889 if (codePath.isDirectory()) {
9890 File codePathParent = codePath.getParentFile();
9892 mInstaller.rmPackageDir(codePath.getAbsolutePath());
9893 if (codePathParent.getName().startsWith(RANDOM_DIR_PREFIX)) {
9894 mInstaller.rmPackageDir(codePathParent.getAbsolutePath());
9896 } catch (InstallerException e) {
9897 Slog.w(TAG, "Failed to remove code path", e);
9904 private int[] resolveUserIds(int userId) {
9905 return (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds() : new int[] { userId };
9908 private void clearAppDataLIF(AndroidPackage pkg, int userId, int flags) {
9910 Slog.wtf(TAG, "Package was null!", new Throwable());
9913 clearAppDataLeafLIF(pkg, userId, flags);
9915 if ((flags & Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES) == 0) {
9916 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
9920 private void clearAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
9921 final PackageSetting ps;
9922 synchronized (mLock) {
9923 ps = mSettings.mPackages.get(pkg.getPackageName());
9925 for (int realUserId : resolveUserIds(userId)) {
9926 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9928 mInstaller.clearAppData(pkg.getVolumeUuid(), pkg.getPackageName(), realUserId,
9929 flags, ceDataInode);
9930 } catch (InstallerException e) {
9931 Slog.w(TAG, String.valueOf(e));
9936 private void destroyAppDataLIF(AndroidPackage pkg, int userId, int flags) {
9938 Slog.wtf(TAG, "Package was null!", new Throwable());
9941 destroyAppDataLeafLIF(pkg, userId, flags);
9944 private void destroyAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
9945 final PackageSetting ps;
9946 synchronized (mLock) {
9947 ps = mSettings.mPackages.get(pkg.getPackageName());
9949 for (int realUserId : resolveUserIds(userId)) {
9950 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9952 mInstaller.destroyAppData(pkg.getVolumeUuid(), pkg.getPackageName(), realUserId,
9953 flags, ceDataInode);
9954 } catch (InstallerException e) {
9955 Slog.w(TAG, String.valueOf(e));
9957 mDexManager.notifyPackageDataDestroyed(pkg.getPackageName(), userId);
9961 private void destroyAppProfilesLIF(AndroidPackage pkg) {
9963 Slog.wtf(TAG, "Package was null!", new Throwable());
9966 destroyAppProfilesLeafLIF(pkg);
9969 private void destroyAppProfilesLeafLIF(AndroidPackage pkg) {
9971 mInstaller.destroyAppProfiles(pkg.getPackageName());
9972 } catch (InstallerException e) {
9973 Slog.w(TAG, String.valueOf(e));
9977 private void clearAppProfilesLIF(AndroidPackage pkg, int userId) {
9979 Slog.wtf(TAG, "Package was null!", new Throwable());
9982 mArtManagerService.clearAppProfiles(pkg);
9986 private void applyDefiningSharedLibraryUpdateLocked(
9987 AndroidPackage pkg, SharedLibraryInfo libInfo,
9988 BiConsumer<SharedLibraryInfo, SharedLibraryInfo> action) {
9989 // Note that libraries defined by this package may be null if:
9990 // - Package manager was unable to create the shared library. The package still
9991 // gets installed, but the shared library does not get created.
9993 // - Package manager is in a state where package isn't scanned yet. This will
9994 // get called again after scanning to fix the dependencies.
9995 if (AndroidPackageUtils.isLibrary(pkg)) {
9996 if (pkg.getStaticSharedLibName() != null) {
9997 SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr(
9998 pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion());
9999 if (definedLibrary != null) {
10000 action.accept(definedLibrary, libInfo);
10003 for (String libraryName : pkg.getLibraryNames()) {
10004 SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr(
10005 libraryName, SharedLibraryInfo.VERSION_UNDEFINED);
10006 if (definedLibrary != null) {
10007 action.accept(definedLibrary, libInfo);
10014 @GuardedBy("mLock")
10015 private void addSharedLibraryLPr(AndroidPackage pkg, Set<String> usesLibraryFiles,
10016 SharedLibraryInfo libInfo, @Nullable AndroidPackage changingLib,
10017 @Nullable PackageSetting changingLibSetting) {
10018 if (libInfo.getPath() != null) {
10019 usesLibraryFiles.add(libInfo.getPath());
10022 AndroidPackage pkgForCodePaths = mPackages.get(libInfo.getPackageName());
10023 PackageSetting pkgSetting = mSettings.getPackageLPr(libInfo.getPackageName());
10024 if (changingLib != null && changingLib.getPackageName().equals(libInfo.getPackageName())) {
10025 // If we are doing this while in the middle of updating a library apk,
10026 // then we need to make sure to use that new apk for determining the
10027 // dependencies here. (We haven't yet finished committing the new apk
10028 // to the package manager state.)
10029 if (pkgForCodePaths == null
10030 || pkgForCodePaths.getPackageName().equals(changingLib.getPackageName())) {
10031 pkgForCodePaths = changingLib;
10032 pkgSetting = changingLibSetting;
10035 if (pkgForCodePaths != null) {
10036 usesLibraryFiles.addAll(AndroidPackageUtils.getAllCodePaths(pkgForCodePaths));
10037 // If the package provides libraries, add the dependency to them.
10038 applyDefiningSharedLibraryUpdateLocked(pkg, libInfo, SharedLibraryInfo::addDependency);
10039 if (pkgSetting != null) {
10040 usesLibraryFiles.addAll(pkgSetting.getPkgState().getUsesLibraryFiles());
10045 @GuardedBy("mLock")
10046 private void updateSharedLibrariesLocked(AndroidPackage pkg, PackageSetting pkgSetting,
10047 @Nullable AndroidPackage changingLib, @Nullable PackageSetting changingLibSetting,
10048 Map<String, AndroidPackage> availablePackages)
10049 throws PackageManagerException {
10050 final ArrayList<SharedLibraryInfo> sharedLibraryInfos = collectSharedLibraryInfos(
10051 pkgSetting.pkg, availablePackages, mSharedLibraries, null);
10052 executeSharedLibrariesUpdateLPr(pkg, pkgSetting, changingLib, changingLibSetting,
10053 sharedLibraryInfos);
10056 private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(AndroidPackage pkg,
10057 Map<String, AndroidPackage> availablePackages,
10058 @NonNull final Map<String, LongSparseArray<SharedLibraryInfo>> existingLibraries,
10059 @Nullable final Map<String, LongSparseArray<SharedLibraryInfo>> newLibraries)
10060 throws PackageManagerException {
10064 // The collection used here must maintain the order of addition (so
10065 // that libraries are searched in the correct order) and must have no
10067 ArrayList<SharedLibraryInfo> usesLibraryInfos = null;
10068 if (!pkg.getUsesLibraries().isEmpty()) {
10069 usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesLibraries(), null, null,
10070 pkg.getPackageName(), true, pkg.getTargetSdkVersion(), null,
10071 availablePackages, existingLibraries, newLibraries);
10073 if (!pkg.getUsesStaticLibraries().isEmpty()) {
10074 usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesStaticLibraries(),
10075 pkg.getUsesStaticLibrariesVersions(), pkg.getUsesStaticLibrariesCertDigests(),
10076 pkg.getPackageName(), true, pkg.getTargetSdkVersion(), usesLibraryInfos,
10077 availablePackages, existingLibraries, newLibraries);
10079 if (!pkg.getUsesOptionalLibraries().isEmpty()) {
10080 usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesOptionalLibraries(),
10081 null, null, pkg.getPackageName(), false, pkg.getTargetSdkVersion(),
10082 usesLibraryInfos, availablePackages, existingLibraries, newLibraries);
10084 return usesLibraryInfos;
10087 private void executeSharedLibrariesUpdateLPr(AndroidPackage pkg,
10088 @NonNull PackageSetting pkgSetting, @Nullable AndroidPackage changingLib,
10089 @Nullable PackageSetting changingLibSetting,
10090 ArrayList<SharedLibraryInfo> usesLibraryInfos) {
10091 // If the package provides libraries, clear their old dependencies.
10092 // This method will set them up again.
10093 applyDefiningSharedLibraryUpdateLocked(pkg, null, (definingLibrary, dependency) -> {
10094 definingLibrary.clearDependencies();
10096 if (usesLibraryInfos != null) {
10097 pkgSetting.getPkgState().setUsesLibraryInfos(usesLibraryInfos);
10098 // Use LinkedHashSet to preserve the order of files added to
10099 // usesLibraryFiles while eliminating duplicates.
10100 Set<String> usesLibraryFiles = new LinkedHashSet<>();
10101 for (SharedLibraryInfo libInfo : usesLibraryInfos) {
10102 addSharedLibraryLPr(pkg, usesLibraryFiles, libInfo, changingLib,
10103 changingLibSetting);
10105 pkgSetting.getPkgState().setUsesLibraryFiles(new ArrayList<>(usesLibraryFiles));
10107 pkgSetting.getPkgState().setUsesLibraryInfos(Collections.emptyList())
10108 .setUsesLibraryFiles(Collections.emptyList());
10112 @GuardedBy("mLock")
10113 private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(
10114 @NonNull List<String> requestedLibraries,
10115 @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
10116 @NonNull String packageName, boolean required, int targetSdk,
10117 @Nullable ArrayList<SharedLibraryInfo> outUsedLibraries,
10118 @NonNull final Map<String, AndroidPackage> availablePackages,
10119 @NonNull final Map<String, LongSparseArray<SharedLibraryInfo>> existingLibraries,
10120 @Nullable final Map<String, LongSparseArray<SharedLibraryInfo>> newLibraries)
10121 throws PackageManagerException {
10122 final int libCount = requestedLibraries.size();
10123 for (int i = 0; i < libCount; i++) {
10124 final String libName = requestedLibraries.get(i);
10125 final long libVersion = requiredVersions != null ? requiredVersions[i]
10126 : SharedLibraryInfo.VERSION_UNDEFINED;
10127 final SharedLibraryInfo libraryInfo = getSharedLibraryInfo(libName, libVersion,
10128 existingLibraries, newLibraries);
10129 if (libraryInfo == null) {
10131 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10132 "Package " + packageName + " requires unavailable shared library "
10133 + libName + "; failing!");
10134 } else if (DEBUG_SHARED_LIBRARIES) {
10135 Slog.i(TAG, "Package " + packageName
10136 + " desires unavailable shared library "
10137 + libName + "; ignoring!");
10140 if (requiredVersions != null && requiredCertDigests != null) {
10141 if (libraryInfo.getLongVersion() != requiredVersions[i]) {
10142 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10143 "Package " + packageName + " requires unavailable static shared"
10144 + " library " + libName + " version "
10145 + libraryInfo.getLongVersion() + "; failing!");
10147 AndroidPackage pkg = availablePackages.get(libraryInfo.getPackageName());
10148 SigningDetails libPkg = pkg == null ? null : pkg.getSigningDetails();
10149 if (libPkg == null) {
10150 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10151 "Package " + packageName + " requires unavailable static shared"
10152 + " library; failing!");
10154 final String[] expectedCertDigests = requiredCertDigests[i];
10155 if (expectedCertDigests.length > 1) {
10156 // For apps targeting O MR1 we require explicit enumeration of all certs.
10157 final String[] libCertDigests = (targetSdk >= Build.VERSION_CODES.O_MR1)
10158 ? PackageUtils.computeSignaturesSha256Digests(
10160 : PackageUtils.computeSignaturesSha256Digests(
10161 new Signature[]{libPkg.signatures[0]});
10163 // Take a shortcut if sizes don't match. Note that if an app doesn't
10164 // target O we don't parse the "additional-certificate" tags similarly
10165 // how we only consider all certs only for apps targeting O (see above).
10166 // Therefore, the size check is safe to make.
10167 if (expectedCertDigests.length != libCertDigests.length) {
10168 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10169 "Package " + packageName + " requires differently signed" +
10170 " static shared library; failing!");
10173 // Use a predictable order as signature order may vary
10174 Arrays.sort(libCertDigests);
10175 Arrays.sort(expectedCertDigests);
10177 final int certCount = libCertDigests.length;
10178 for (int j = 0; j < certCount; j++) {
10179 if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
10180 throw new PackageManagerException(
10181 INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10182 "Package " + packageName + " requires differently signed" +
10183 " static shared library; failing!");
10187 // lib signing cert could have rotated beyond the one expected, check to see
10188 // if the new one has been blessed by the old
10189 byte[] digestBytes = HexEncoding.decode(
10190 expectedCertDigests[0], false /* allowSingleChar */);
10191 if (!libPkg.hasSha256Certificate(digestBytes)) {
10192 throw new PackageManagerException(
10193 INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10194 "Package " + packageName + " requires differently signed" +
10195 " static shared library; failing!");
10199 if (outUsedLibraries == null) {
10200 outUsedLibraries = new ArrayList<>();
10202 outUsedLibraries.add(libraryInfo);
10205 return outUsedLibraries;
10208 private static boolean hasString(List<String> list, List<String> which) {
10209 if (list == null || which == null) {
10212 for (int i=list.size()-1; i>=0; i--) {
10213 for (int j=which.size()-1; j>=0; j--) {
10214 if (which.get(j).equals(list.get(i))) {
10222 @GuardedBy("mLock")
10223 private ArrayList<AndroidPackage> updateAllSharedLibrariesLocked(
10224 @Nullable AndroidPackage updatedPkg, @Nullable PackageSetting updatedPkgSetting,
10225 Map<String, AndroidPackage> availablePackages) {
10226 ArrayList<AndroidPackage> resultList = null;
10227 // Set of all descendants of a library; used to eliminate cycles
10228 ArraySet<String> descendants = null;
10229 // The current list of packages that need updating
10230 List<Pair<AndroidPackage, PackageSetting>> needsUpdating = null;
10231 if (updatedPkg != null && updatedPkgSetting != null) {
10232 needsUpdating = new ArrayList<>(1);
10233 needsUpdating.add(Pair.create(updatedPkg, updatedPkgSetting));
10236 final Pair<AndroidPackage, PackageSetting> changingPkgPair =
10237 (needsUpdating == null) ? null : needsUpdating.remove(0);
10238 final AndroidPackage changingPkg = changingPkgPair != null
10239 ? changingPkgPair.first : null;
10240 final PackageSetting changingPkgSetting = changingPkgPair != null
10241 ? changingPkgPair.second : null;
10242 for (int i = mPackages.size() - 1; i >= 0; --i) {
10243 final AndroidPackage pkg = mPackages.valueAt(i);
10244 final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.getPackageName());
10245 if (changingPkg != null
10246 && !hasString(pkg.getUsesLibraries(), changingPkg.getLibraryNames())
10247 && !hasString(pkg.getUsesOptionalLibraries(), changingPkg.getLibraryNames())
10248 && !ArrayUtils.contains(pkg.getUsesStaticLibraries(),
10249 changingPkg.getStaticSharedLibName())) {
10252 if (resultList == null) {
10253 resultList = new ArrayList<>();
10255 resultList.add(pkg);
10256 // if we're updating a shared library, all of its descendants must be updated
10257 if (changingPkg != null) {
10258 if (descendants == null) {
10259 descendants = new ArraySet<>();
10261 if (!descendants.contains(pkg.getPackageName())) {
10262 descendants.add(pkg.getPackageName());
10263 needsUpdating.add(Pair.create(pkg, pkgSetting));
10267 updateSharedLibrariesLocked(pkg, pkgSetting, changingPkg,
10268 changingPkgSetting, availablePackages);
10269 } catch (PackageManagerException e) {
10270 // If a system app update or an app and a required lib missing we
10271 // delete the package and for updated system apps keep the data as
10272 // it is better for the user to reinstall than to be in an limbo
10273 // state. Also libs disappearing under an app should never happen
10275 if (!pkg.isSystem() || pkgSetting.getPkgState().isUpdatedSystemApp()) {
10276 final int flags = pkgSetting.getPkgState().isUpdatedSystemApp()
10277 ? PackageManager.DELETE_KEEP_DATA : 0;
10278 deletePackageLIF(pkg.getPackageName(), null, true,
10279 mUserManager.getUserIds(), flags, null,
10282 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
10285 } while (needsUpdating != null && needsUpdating.size() > 0);
10289 @GuardedBy({"mInstallLock", "mLock"})
10290 private ScanResult scanPackageTracedLI(ParsedPackage parsedPackage,
10291 final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
10292 @Nullable UserHandle user, String cpuAbiOverride) throws PackageManagerException {
10293 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
10295 return scanPackageNewLI(parsedPackage, parseFlags, scanFlags, currentTime, user,
10298 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10302 /** The result of a package scan. */
10304 static class ScanResult {
10305 /** The request that initiated the scan that produced this result. */
10306 public final ScanRequest request;
10307 /** Whether or not the package scan was successful */
10308 public final boolean success;
10310 * Whether or not the original PackageSetting needs to be updated with this result on
10313 public final boolean existingSettingCopied;
10315 * The final package settings. This may be the same object passed in
10316 * the {@link ScanRequest}, but, with modified values.
10318 @Nullable public final PackageSetting pkgSetting;
10319 /** ABI code paths that have changed in the package scan */
10320 @Nullable public final List<String> changedAbiCodePath;
10322 public final SharedLibraryInfo staticSharedLibraryInfo;
10324 public final List<SharedLibraryInfo> dynamicSharedLibraryInfos;
10327 ScanRequest request, boolean success,
10328 @Nullable PackageSetting pkgSetting,
10329 @Nullable List<String> changedAbiCodePath, boolean existingSettingCopied,
10330 SharedLibraryInfo staticSharedLibraryInfo,
10331 List<SharedLibraryInfo> dynamicSharedLibraryInfos) {
10332 this.request = request;
10333 this.success = success;
10334 this.pkgSetting = pkgSetting;
10335 this.changedAbiCodePath = changedAbiCodePath;
10336 this.existingSettingCopied = existingSettingCopied;
10337 this.staticSharedLibraryInfo = staticSharedLibraryInfo;
10338 this.dynamicSharedLibraryInfos = dynamicSharedLibraryInfos;
10342 /** A package to be scanned */
10344 static class ScanRequest {
10345 /** The parsed package */
10346 @NonNull public final ParsedPackage parsedPackage;
10347 /** The package this package replaces */
10348 @Nullable public final AndroidPackage oldPkg;
10349 /** Shared user settings, if the package has a shared user */
10350 @Nullable public final SharedUserSetting sharedUserSetting;
10352 * Package settings of the currently installed version.
10353 * <p><em>IMPORTANT:</em> The contents of this object may be modified
10356 @Nullable public final PackageSetting pkgSetting;
10357 /** A copy of the settings for the currently installed version */
10358 @Nullable public final PackageSetting oldPkgSetting;
10359 /** Package settings for the disabled version on the /system partition */
10360 @Nullable public final PackageSetting disabledPkgSetting;
10361 /** Package settings for the installed version under its original package name */
10362 @Nullable public final PackageSetting originalPkgSetting;
10363 /** The real package name of a renamed application */
10364 @Nullable public final String realPkgName;
10365 public final @ParseFlags int parseFlags;
10366 public final @ScanFlags int scanFlags;
10367 /** The user for which the package is being scanned */
10368 @Nullable public final UserHandle user;
10369 /** Whether or not the platform package is being scanned */
10370 public final boolean isPlatformPackage;
10371 /** Override value for package ABI if set during install */
10373 public final String cpuAbiOverride;
10374 public ScanRequest(
10375 @NonNull ParsedPackage parsedPackage,
10376 @Nullable SharedUserSetting sharedUserSetting,
10377 @Nullable AndroidPackage oldPkg,
10378 @Nullable PackageSetting pkgSetting,
10379 @Nullable PackageSetting disabledPkgSetting,
10380 @Nullable PackageSetting originalPkgSetting,
10381 @Nullable String realPkgName,
10382 @ParseFlags int parseFlags,
10383 @ScanFlags int scanFlags,
10384 boolean isPlatformPackage,
10385 @Nullable UserHandle user,
10386 @Nullable String cpuAbiOverride) {
10387 this.parsedPackage = parsedPackage;
10388 this.oldPkg = oldPkg;
10389 this.pkgSetting = pkgSetting;
10390 this.sharedUserSetting = sharedUserSetting;
10391 this.oldPkgSetting = pkgSetting == null ? null : new PackageSetting(pkgSetting);
10392 this.disabledPkgSetting = disabledPkgSetting;
10393 this.originalPkgSetting = originalPkgSetting;
10394 this.realPkgName = realPkgName;
10395 this.parseFlags = parseFlags;
10396 this.scanFlags = scanFlags;
10397 this.isPlatformPackage = isPlatformPackage;
10399 this.cpuAbiOverride = cpuAbiOverride;
10404 * Returns the actual scan flags depending upon the state of the other settings.
10405 * <p>Updated system applications will not have the following flags set
10406 * by default and need to be adjusted after the fact:
10408 * <li>{@link #SCAN_AS_SYSTEM}</li>
10409 * <li>{@link #SCAN_AS_PRIVILEGED}</li>
10410 * <li>{@link #SCAN_AS_OEM}</li>
10411 * <li>{@link #SCAN_AS_VENDOR}</li>
10412 * <li>{@link #SCAN_AS_PRODUCT}</li>
10413 * <li>{@link #SCAN_AS_SYSTEM_EXT}</li>
10414 * <li>{@link #SCAN_AS_INSTANT_APP}</li>
10415 * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
10416 * <li>{@link #SCAN_AS_ODM}</li>
10419 private @ScanFlags int adjustScanFlags(@ScanFlags int scanFlags,
10420 PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user,
10421 AndroidPackage pkg) {
10423 // TODO(patb): Do away entirely with disabledPkgSetting here. PkgSetting will always contain
10424 // the correct isSystem value now that we don't disable system packages before scan.
10425 final PackageSetting systemPkgSetting =
10426 (scanFlags & SCAN_NEW_INSTALL) != 0 && disabledPkgSetting == null
10427 && pkgSetting != null && pkgSetting.isSystem()
10429 : disabledPkgSetting;
10430 if (systemPkgSetting != null) {
10431 // updated system application, must at least have SCAN_AS_SYSTEM
10432 scanFlags |= SCAN_AS_SYSTEM;
10433 if ((systemPkgSetting.pkgPrivateFlags
10434 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
10435 scanFlags |= SCAN_AS_PRIVILEGED;
10437 if ((systemPkgSetting.pkgPrivateFlags
10438 & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
10439 scanFlags |= SCAN_AS_OEM;
10441 if ((systemPkgSetting.pkgPrivateFlags
10442 & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
10443 scanFlags |= SCAN_AS_VENDOR;
10445 if ((systemPkgSetting.pkgPrivateFlags
10446 & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0) {
10447 scanFlags |= SCAN_AS_PRODUCT;
10449 if ((systemPkgSetting.pkgPrivateFlags
10450 & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0) {
10451 scanFlags |= SCAN_AS_SYSTEM_EXT;
10453 if ((systemPkgSetting.pkgPrivateFlags
10454 & ApplicationInfo.PRIVATE_FLAG_ODM) != 0) {
10455 scanFlags |= SCAN_AS_ODM;
10458 if (pkgSetting != null) {
10459 final int userId = ((user == null) ? 0 : user.getIdentifier());
10460 if (pkgSetting.getInstantApp(userId)) {
10461 scanFlags |= SCAN_AS_INSTANT_APP;
10463 if (pkgSetting.getVirtulalPreload(userId)) {
10464 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
10468 // Scan as privileged apps that share a user with a priv-app.
10469 final boolean skipVendorPrivilegeScan = ((scanFlags & SCAN_AS_VENDOR) != 0)
10470 && SystemProperties.getInt("ro.vndk.version", 28) < 28;
10471 if (((scanFlags & SCAN_AS_PRIVILEGED) == 0)
10472 && !pkg.isPrivileged()
10473 && (pkg.getSharedUserId() != null)
10474 && !skipVendorPrivilegeScan) {
10475 SharedUserSetting sharedUserSetting = null;
10477 sharedUserSetting = mSettings.getSharedUserLPw(pkg.getSharedUserId(), 0,
10479 } catch (PackageManagerException ignore) {
10481 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
10482 // Exempt SharedUsers signed with the platform key.
10483 // TODO(b/72378145) Fix this exemption. Force signature apps
10484 // to whitelist their privileged permissions just like other
10486 synchronized (mLock) {
10487 PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
10488 if ((compareSignatures(platformPkgSetting.signatures.mSigningDetails.signatures,
10489 pkg.getSigningDetails().signatures)
10490 != PackageManager.SIGNATURE_MATCH)) {
10491 scanFlags |= SCAN_AS_PRIVILEGED;
10500 // TODO: scanPackageNewLI() and scanPackageOnly() should be merged. But, first, commiting
10501 // the results / removing app data needs to be moved up a level to the callers of this
10502 // method. Also, we need to solve the problem of potentially creating a new shared user
10503 // setting. That can probably be done later and patch things up after the fact.
10504 @GuardedBy({"mInstallLock", "mLock"})
10505 private ScanResult scanPackageNewLI(@NonNull ParsedPackage parsedPackage,
10506 final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
10507 @Nullable UserHandle user, String cpuAbiOverride) throws PackageManagerException {
10509 final String renamedPkgName = mSettings.getRenamedPackageLPr(
10510 parsedPackage.getRealPackage());
10511 final String realPkgName = getRealPackageName(parsedPackage, renamedPkgName);
10512 if (realPkgName != null) {
10513 ensurePackageRenamed(parsedPackage, renamedPkgName);
10515 final PackageSetting originalPkgSetting = getOriginalPackageLocked(parsedPackage,
10517 final PackageSetting pkgSetting = mSettings.getPackageLPr(parsedPackage.getPackageName());
10518 final PackageSetting disabledPkgSetting =
10519 mSettings.getDisabledSystemPkgLPr(parsedPackage.getPackageName());
10521 if (mTransferredPackages.contains(parsedPackage.getPackageName())) {
10522 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
10523 + " was transferred to another, but its .apk remains");
10526 scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, parsedPackage);
10527 synchronized (mLock) {
10528 boolean isUpdatedSystemApp;
10529 if (pkgSetting != null) {
10530 isUpdatedSystemApp = pkgSetting.getPkgState().isUpdatedSystemApp();
10532 isUpdatedSystemApp = disabledPkgSetting != null;
10534 applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, isUpdatedSystemApp);
10535 assertPackageIsValid(parsedPackage, parseFlags, scanFlags);
10537 SharedUserSetting sharedUserSetting = null;
10538 if (parsedPackage.getSharedUserId() != null) {
10539 // SIDE EFFECTS; may potentially allocate a new shared user
10540 sharedUserSetting = mSettings.getSharedUserLPw(parsedPackage.getSharedUserId(),
10541 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
10542 if (DEBUG_PACKAGE_SCANNING) {
10543 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
10544 Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId()
10545 + " (uid=" + sharedUserSetting.userId + "):"
10546 + " packages=" + sharedUserSetting.packages);
10549 String platformPackageName = mPlatformPackage == null
10550 ? null : mPlatformPackage.getPackageName();
10551 final ScanRequest request = new ScanRequest(parsedPackage, sharedUserSetting,
10552 pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting,
10553 originalPkgSetting, realPkgName, parseFlags, scanFlags,
10554 Objects.equals(parsedPackage.getPackageName(), platformPackageName), user,
10556 return scanPackageOnlyLI(request, mInjector, mFactoryTest, currentTime);
10562 * Prepares the system to commit a {@link ScanResult} in a way that will not fail by registering
10563 * the app ID required for reconcile.
10564 * @return {@code true} if a new app ID was registered and will need to be cleaned up on
10567 private boolean optimisticallyRegisterAppId(@NonNull ScanResult result)
10568 throws PackageManagerException {
10569 if (!result.existingSettingCopied) {
10570 // THROWS: when we can't allocate a user id. add call to check if there's
10571 // enough space to ensure we won't throw; otherwise, don't modify state
10572 return mSettings.registerAppIdLPw(result.pkgSetting);
10578 * Reverts any app ID creation that were made by
10579 * {@link #optimisticallyRegisterAppId(ScanResult)}. Note: this is only necessary if the
10580 * referenced method returned true.
10582 private void cleanUpAppIdCreation(@NonNull ScanResult result) {
10583 // iff we've acquired an app ID for a new package setting, remove it so that it can be
10584 // acquired by another request.
10585 if (result.pkgSetting.appId > 0) {
10586 mSettings.removeAppIdLPw(result.pkgSetting.appId);
10591 * Commits the package scan and modifies system state.
10592 * <p><em>WARNING:</em> The method may throw an excpetion in the middle
10593 * of committing the package, leaving the system in an inconsistent state.
10594 * This needs to be fixed so, once we get to this point, no errors are
10595 * possible and the system is not left in an inconsistent state.
10597 @GuardedBy({"mLock", "mInstallLock"})
10598 private AndroidPackage commitReconciledScanResultLocked(
10599 @NonNull ReconciledPackage reconciledPkg) {
10600 final ScanResult result = reconciledPkg.scanResult;
10601 final ScanRequest request = result.request;
10602 // TODO(b/135203078): Move this even further away
10603 ParsedPackage parsedPackage = request.parsedPackage;
10604 if ("android".equals(parsedPackage.getPackageName())) {
10605 // TODO(b/135203078): Move this to initial parse
10606 parsedPackage.setVersionCode(mSdkVersion)
10607 .setVersionCodeMajor(0);
10609 final AndroidPackage oldPkg = request.oldPkg;
10610 final @ParseFlags int parseFlags = request.parseFlags;
10611 final @ScanFlags int scanFlags = request.scanFlags;
10612 final PackageSetting oldPkgSetting = request.oldPkgSetting;
10613 final PackageSetting originalPkgSetting = request.originalPkgSetting;
10614 final UserHandle user = request.user;
10615 final String realPkgName = request.realPkgName;
10616 final List<String> changedAbiCodePath = result.changedAbiCodePath;
10617 final PackageSetting pkgSetting;
10618 if (request.pkgSetting != null && request.pkgSetting.sharedUser != null
10619 && request.pkgSetting.sharedUser != result.pkgSetting.sharedUser) {
10620 // shared user changed, remove from old shared user
10621 request.pkgSetting.sharedUser.removePackage(request.pkgSetting);
10623 if (result.existingSettingCopied) {
10624 pkgSetting = request.pkgSetting;
10625 pkgSetting.updateFrom(result.pkgSetting);
10627 pkgSetting = result.pkgSetting;
10628 if (originalPkgSetting != null) {
10629 mSettings.addRenamedPackageLPw(parsedPackage.getPackageName(),
10630 originalPkgSetting.name);
10631 mTransferredPackages.add(originalPkgSetting.name);
10634 if (pkgSetting.sharedUser != null) {
10635 pkgSetting.sharedUser.addPackage(pkgSetting);
10637 if (reconciledPkg.installArgs != null && reconciledPkg.installArgs.forceQueryableOverride) {
10638 pkgSetting.forceQueryableOverride = true;
10641 // TODO(toddke): Consider a method specifically for modifying the Package object
10642 // post scan; or, moving this stuff out of the Package object since it has nothing
10643 // to do with the package on disk.
10644 // We need to have this here because addUserToSettingLPw() is sometimes responsible
10645 // for creating the application ID. If we did this earlier, we would be saving the
10647 parsedPackage.setUid(pkgSetting.appId);
10648 final AndroidPackage pkg = parsedPackage.hideAsFinal();
10650 mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
10652 if (realPkgName != null) {
10653 mTransferredPackages.add(pkg.getPackageName());
10656 if (reconciledPkg.collectedSharedLibraryInfos != null) {
10657 executeSharedLibrariesUpdateLPr(pkg, pkgSetting, null, null,
10658 reconciledPkg.collectedSharedLibraryInfos);
10661 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
10662 if (reconciledPkg.removeAppKeySetData) {
10663 ksms.removeAppKeySetDataLPw(pkg.getPackageName());
10665 if (reconciledPkg.sharedUserSignaturesChanged) {
10666 pkgSetting.sharedUser.signaturesChanged = Boolean.TRUE;
10667 pkgSetting.sharedUser.signatures.mSigningDetails = reconciledPkg.signingDetails;
10669 pkgSetting.signatures.mSigningDetails = reconciledPkg.signingDetails;
10671 if (!pkg.getAdoptPermissions().isEmpty()) {
10672 // This package wants to adopt ownership of permissions from
10673 // another package.
10674 for (int i = pkg.getAdoptPermissions().size() - 1; i >= 0; i--) {
10675 final String origName = pkg.getAdoptPermissions().get(i);
10676 final PackageSetting orig = mSettings.getPackageLPr(origName);
10677 if (orig != null) {
10678 if (verifyPackageUpdateLPr(orig, pkg)) {
10679 Slog.i(TAG, "Adopting permissions from " + origName + " to "
10680 + pkg.getPackageName());
10681 mSettings.mPermissions.transferPermissions(origName, pkg.getPackageName());
10687 if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
10688 for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
10689 final String codePathString = changedAbiCodePath.get(i);
10691 mInstaller.rmdex(codePathString,
10692 getDexCodeInstructionSet(getPreferredInstructionSet()));
10693 } catch (InstallerException ignored) {
10698 final int userId = user == null ? 0 : user.getIdentifier();
10699 // Modify state for the given package setting
10700 commitPackageSettings(pkg, oldPkg, pkgSetting, scanFlags,
10701 (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/, reconciledPkg);
10702 if (pkgSetting.getInstantApp(userId)) {
10703 mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
10710 * Returns the "real" name of the package.
10711 * <p>This may differ from the package's actual name if the application has already
10712 * been installed under one of this package's original names.
10714 private static @Nullable String getRealPackageName(@NonNull AndroidPackage pkg,
10715 @Nullable String renamedPkgName) {
10716 if (isPackageRenamed(pkg, renamedPkgName)) {
10717 return pkg.getRealPackage();
10722 /** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */
10723 private static boolean isPackageRenamed(@NonNull AndroidPackage pkg,
10724 @Nullable String renamedPkgName) {
10725 return pkg.getOriginalPackages().contains(renamedPkgName);
10729 * Returns the original package setting.
10730 * <p>A package can migrate its name during an update. In this scenario, a package
10731 * designates a set of names that it considers as one of its original names.
10732 * <p>An original package must be signed identically and it must have the same
10733 * shared user [if any].
10735 @GuardedBy("mLock")
10736 private @Nullable PackageSetting getOriginalPackageLocked(@NonNull AndroidPackage pkg,
10737 @Nullable String renamedPkgName) {
10738 if (!isPackageRenamed(pkg, renamedPkgName)) {
10741 for (int i = ArrayUtils.size(pkg.getOriginalPackages()) - 1; i >= 0; --i) {
10742 final PackageSetting originalPs =
10743 mSettings.getPackageLPr(pkg.getOriginalPackages().get(i));
10744 if (originalPs != null) {
10745 // the package is already installed under its original name...
10746 // but, should we use it?
10747 if (!verifyPackageUpdateLPr(originalPs, pkg)) {
10748 // the new package is incompatible with the original
10750 } else if (originalPs.sharedUser != null) {
10751 if (!originalPs.sharedUser.name.equals(pkg.getSharedUserId())) {
10752 // the shared user id is incompatible with the original
10753 Slog.w(TAG, "Unable to migrate data from " + originalPs.name
10754 + " to " + pkg.getPackageName() + ": old uid "
10755 + originalPs.sharedUser.name
10756 + " differs from " + pkg.getSharedUserId());
10759 // TODO: Add case when shared user id is added [b/28144775]
10761 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10762 + pkg.getPackageName() + " to old name " + originalPs.name);
10771 * Renames the package if it was installed under a different name.
10772 * <p>When we've already installed the package under an original name, update
10773 * the new package so we can continue to have the old name.
10775 private static void ensurePackageRenamed(@NonNull ParsedPackage parsedPackage,
10776 @NonNull String renamedPackageName) {
10777 if (!parsedPackage.getOriginalPackages().contains(renamedPackageName)
10778 || parsedPackage.getPackageName().equals(renamedPackageName)) {
10781 parsedPackage.setPackageName(renamedPackageName);
10785 * Applies the adjusted ABI calculated by
10786 * {@link PackageAbiHelper#getAdjustedAbiForSharedUser(Set, AndroidPackage)} to all
10787 * relevant packages and settings.
10788 * @param sharedUserSetting The {@code SharedUserSetting} to adjust
10789 * @param scannedPackage the package being scanned or null
10790 * @param adjustedAbi the adjusted ABI calculated by {@link PackageAbiHelper}
10791 * @return the list of code paths that belong to packages that had their ABIs adjusted.
10793 private static List<String> applyAdjustedAbiToSharedUser(SharedUserSetting sharedUserSetting,
10794 ParsedPackage scannedPackage, String adjustedAbi) {
10795 if (scannedPackage != null) {
10796 scannedPackage.setPrimaryCpuAbi(adjustedAbi);
10798 List<String> changedAbiCodePath = null;
10799 for (PackageSetting ps : sharedUserSetting.packages) {
10800 if (scannedPackage == null || !scannedPackage.getPackageName().equals(ps.name)) {
10801 if (ps.primaryCpuAbiString != null) {
10805 ps.primaryCpuAbiString = adjustedAbi;
10806 if (ps.pkg != null) {
10807 if (!TextUtils.equals(adjustedAbi,
10808 AndroidPackageUtils.getRawPrimaryCpuAbi(ps.pkg))) {
10809 if (DEBUG_ABI_SELECTION) {
10811 "Adjusting ABI for " + ps.name + " to " + adjustedAbi
10812 + " (scannedPackage="
10813 + (scannedPackage != null ? scannedPackage : "null")
10816 if (changedAbiCodePath == null) {
10817 changedAbiCodePath = new ArrayList<>();
10819 changedAbiCodePath.add(ps.codePathString);
10824 return changedAbiCodePath;
10828 * Sets the enabled state of components configured through {@link SystemConfig}.
10829 * This modifies the {@link PackageSetting} object.
10831 * TODO(b/135203078): Move this to package parsing
10833 static void configurePackageComponents(AndroidPackage pkg) {
10834 final ArrayMap<String, Boolean> componentsEnabledStates = SystemConfig.getInstance()
10835 .getComponentsEnabledStates(pkg.getPackageName());
10836 if (componentsEnabledStates == null) {
10840 for (int i = ArrayUtils.size(pkg.getActivities()) - 1; i >= 0; i--) {
10841 final ParsedActivity component = pkg.getActivities().get(i);
10842 final Boolean enabled = componentsEnabledStates.get(component.getName());
10843 if (enabled != null) {
10844 component.setEnabled(enabled);
10848 for (int i = ArrayUtils.size(pkg.getReceivers()) - 1; i >= 0; i--) {
10849 final ParsedActivity component = pkg.getReceivers().get(i);
10850 final Boolean enabled = componentsEnabledStates.get(component.getName());
10851 if (enabled != null) {
10852 component.setEnabled(enabled);
10856 for (int i = ArrayUtils.size(pkg.getProviders()) - 1; i >= 0; i--) {
10857 final ParsedProvider component = pkg.getProviders().get(i);
10858 final Boolean enabled = componentsEnabledStates.get(component.getName());
10859 if (enabled != null) {
10860 component.setEnabled(enabled);
10864 for (int i = ArrayUtils.size(pkg.getServices()) - 1; i >= 0; i--) {
10865 final ParsedService component = pkg.getServices().get(i);
10866 final Boolean enabled = componentsEnabledStates.get(component.getName());
10867 if (enabled != null) {
10868 component.setEnabled(enabled);
10875 * Just scans the package without any side effects.
10876 * <p>Not entirely true at the moment. There is still one side effect -- this
10877 * method potentially modifies a live {@link PackageSetting} object representing
10878 * the package being scanned. This will be resolved in the future.
10880 * @param injector injector for acquiring dependencies
10881 * @param request Information about the package to be scanned
10882 * @param isUnderFactoryTest Whether or not the device is under factory test
10883 * @param currentTime The current time, in millis
10884 * @return The results of the scan
10886 @GuardedBy("mInstallLock")
10889 static ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
10891 boolean isUnderFactoryTest, long currentTime)
10892 throws PackageManagerException {
10893 final PackageAbiHelper packageAbiHelper = injector.getAbiHelper();
10894 final UserManagerInternal userManager = injector.getUserManagerInternal();
10895 ParsedPackage parsedPackage = request.parsedPackage;
10896 PackageSetting pkgSetting = request.pkgSetting;
10897 final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
10898 final PackageSetting originalPkgSetting = request.originalPkgSetting;
10899 final @ParseFlags int parseFlags = request.parseFlags;
10900 final @ScanFlags int scanFlags = request.scanFlags;
10901 final String realPkgName = request.realPkgName;
10902 final SharedUserSetting sharedUserSetting = request.sharedUserSetting;
10903 final UserHandle user = request.user;
10904 final boolean isPlatformPackage = request.isPlatformPackage;
10906 List<String> changedAbiCodePath = null;
10908 if (DEBUG_PACKAGE_SCANNING) {
10909 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
10910 Log.d(TAG, "Scanning package " + parsedPackage.getPackageName());
10913 // Initialize package source and resource directories
10914 final File destCodeFile = new File(parsedPackage.getCodePath());
10915 final File destResourceFile = new File(parsedPackage.getCodePath());
10917 // We keep references to the derived CPU Abis from settings in oder to reuse
10918 // them in the case where we're not upgrading or booting for the first time.
10919 String primaryCpuAbiFromSettings = null;
10920 String secondaryCpuAbiFromSettings = null;
10921 boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
10922 if (!needToDeriveAbi) {
10923 if (pkgSetting != null) {
10924 primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
10925 secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
10927 // Re-scanning a system package after uninstalling updates; need to derive ABI
10928 needToDeriveAbi = true;
10932 if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) {
10933 PackageManagerService.reportSettingsProblem(Log.WARN,
10934 "Package " + parsedPackage.getPackageName() + " shared user changed from "
10935 + (pkgSetting.sharedUser != null
10936 ? pkgSetting.sharedUser.name : "<nothing>")
10938 + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
10939 + "; replacing with new");
10943 String[] usesStaticLibraries = null;
10944 if (!parsedPackage.getUsesStaticLibraries().isEmpty()) {
10945 usesStaticLibraries = new String[parsedPackage.getUsesStaticLibraries().size()];
10946 parsedPackage.getUsesStaticLibraries().toArray(usesStaticLibraries);
10948 // TODO(b/135203078): Remove appInfoFlag usage in favor of individually assigned booleans
10949 // to avoid adding something that's unsupported due to lack of state, since it's called
10951 final boolean createNewPackage = (pkgSetting == null);
10952 if (createNewPackage) {
10953 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10954 final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
10955 // REMOVE SharedUserSetting from method; update in a separate call
10956 pkgSetting = Settings.createNewSetting(parsedPackage.getPackageName(),
10957 originalPkgSetting, disabledPkgSetting, realPkgName, sharedUserSetting,
10958 destCodeFile, destResourceFile, parsedPackage.getNativeLibraryRootDir(),
10959 AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage),
10960 AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage),
10961 parsedPackage.getVersionCode(),
10962 PackageInfoWithoutStateUtils.appInfoFlags(parsedPackage),
10963 PackageInfoWithoutStateUtils.appInfoPrivateFlags(parsedPackage),
10964 user, true /*allowInstall*/, instantApp,
10965 virtualPreload, UserManagerService.getInstance(), usesStaticLibraries,
10966 parsedPackage.getUsesStaticLibrariesVersions(), parsedPackage.getMimeGroups());
10968 // make a deep copy to avoid modifying any existing system state.
10969 pkgSetting = new PackageSetting(pkgSetting);
10970 pkgSetting.pkg = parsedPackage;
10972 // REMOVE SharedUserSetting from method; update in a separate call.
10974 // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10975 // secondaryCpuAbi are not known at this point so we always update them
10976 // to null here, only to reset them at a later point.
10977 Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting,
10978 destCodeFile, destResourceFile, parsedPackage.getNativeLibraryDir(),
10979 AndroidPackageUtils.getPrimaryCpuAbi(parsedPackage, pkgSetting),
10980 AndroidPackageUtils.getSecondaryCpuAbi(parsedPackage, pkgSetting),
10981 PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting),
10982 PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting),
10983 UserManagerService.getInstance(),
10984 usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions(),
10985 parsedPackage.getMimeGroups());
10987 if (createNewPackage && originalPkgSetting != null) {
10988 // This is the initial transition from the original package, so,
10989 // fix up the new package's name now. We must do this after looking
10990 // up the package under its new name, so getPackageLP takes care of
10991 // fiddling things correctly.
10992 parsedPackage.setPackageName(originalPkgSetting.name);
10994 // File a report about this.
10995 String msg = "New package " + pkgSetting.realName
10996 + " renamed to replace old package " + pkgSetting.name;
10997 reportSettingsProblem(Log.WARN, msg);
11000 final int userId = (user == null ? UserHandle.USER_SYSTEM : user.getIdentifier());
11001 // for existing packages, change the install state; but, only if it's explicitly specified
11002 if (!createNewPackage) {
11003 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
11004 final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
11005 setInstantAppForUser(injector, pkgSetting, userId, instantApp, fullApp);
11007 // TODO(patb): see if we can do away with disabled check here.
11008 if (disabledPkgSetting != null
11009 || (0 != (scanFlags & SCAN_NEW_INSTALL)
11010 && pkgSetting != null && pkgSetting.isSystem())) {
11011 pkgSetting.getPkgState().setUpdatedSystemApp(true);
11015 .setSeInfo(SELinuxMMAC.getSeInfo(parsedPackage, sharedUserSetting,
11016 injector.getCompatibility()))
11017 .setSeInfoUser(SELinuxUtil.assignSeinfoUser(pkgSetting.readUserState(
11018 userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM : userId)));
11020 if (parsedPackage.isSystem()) {
11021 configurePackageComponents(parsedPackage);
11024 final String cpuAbiOverride = deriveAbiOverride(request.cpuAbiOverride, pkgSetting);
11026 if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
11027 if (needToDeriveAbi) {
11028 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
11029 final boolean extractNativeLibs = !AndroidPackageUtils.isLibrary(parsedPackage);
11030 final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> derivedAbi =
11031 packageAbiHelper.derivePackageAbi(parsedPackage,
11032 pkgSetting.getPkgState().isUpdatedSystemApp(), cpuAbiOverride,
11033 extractNativeLibs);
11034 derivedAbi.first.applyTo(parsedPackage);
11035 derivedAbi.second.applyTo(parsedPackage);
11036 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11038 // Some system apps still use directory structure for native libraries
11039 // in which case we might end up not detecting abi solely based on apk
11040 // structure. Try to detect abi based on directory structure.
11042 String pkgRawPrimaryCpuAbi = AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage);
11043 if (parsedPackage.isSystem() && !pkgSetting.getPkgState().isUpdatedSystemApp() &&
11044 pkgRawPrimaryCpuAbi == null) {
11045 final PackageAbiHelper.Abis abis = packageAbiHelper.getBundledAppAbis(
11047 abis.applyTo(parsedPackage);
11048 abis.applyTo(pkgSetting);
11049 final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
11050 packageAbiHelper.getNativeLibraryPaths(parsedPackage, pkgSetting,
11051 sAppLib32InstallDir);
11052 nativeLibraryPaths.applyTo(parsedPackage);
11055 // This is not a first boot or an upgrade, don't bother deriving the
11056 // ABI during the scan. Instead, trust the value that was stored in the
11057 // package setting.
11058 parsedPackage.setPrimaryCpuAbi(primaryCpuAbiFromSettings)
11059 .setSecondaryCpuAbi(secondaryCpuAbiFromSettings);
11061 final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
11062 packageAbiHelper.getNativeLibraryPaths(parsedPackage,
11063 pkgSetting, sAppLib32InstallDir);
11064 nativeLibraryPaths.applyTo(parsedPackage);
11066 if (DEBUG_ABI_SELECTION) {
11067 Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
11068 parsedPackage.getPackageName() + " " +
11069 AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage)
11071 + AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage));
11075 if ((scanFlags & SCAN_MOVE) != 0) {
11076 // We haven't run dex-opt for this move (since we've moved the compiled output too)
11077 // but we already have this packages package info in the PackageSetting. We just
11078 // use that and derive the native library path based on the new codepath.
11079 parsedPackage.setPrimaryCpuAbi(pkgSetting.primaryCpuAbiString)
11080 .setSecondaryCpuAbi(pkgSetting.secondaryCpuAbiString);
11083 // Set native library paths again. For moves, the path will be updated based on the
11084 // ABIs we've determined above. For non-moves, the path will be updated based on the
11085 // ABIs we determined during compilation, but the path will depend on the final
11086 // package path (after the rename away from the stage path).
11087 final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
11088 packageAbiHelper.getNativeLibraryPaths(parsedPackage, pkgSetting,
11089 sAppLib32InstallDir);
11090 nativeLibraryPaths.applyTo(parsedPackage);
11093 // This is a special case for the "system" package, where the ABI is
11094 // dictated by the zygote configuration (and init.rc). We should keep track
11095 // of this ABI so that we can deal with "normal" applications that run under
11096 // the same UID correctly.
11097 if (isPlatformPackage) {
11098 parsedPackage.setPrimaryCpuAbi(VMRuntime.getRuntime().is64Bit() ?
11099 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]);
11102 // If there's a mismatch between the abi-override in the package setting
11103 // and the abiOverride specified for the install. Warn about this because we
11104 // would've already compiled the app without taking the package setting into
11106 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
11107 if (cpuAbiOverride == null) {
11108 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
11109 " for package " + parsedPackage.getPackageName());
11113 pkgSetting.primaryCpuAbiString = AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage);
11114 pkgSetting.secondaryCpuAbiString = AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage);
11115 pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
11117 if (DEBUG_ABI_SELECTION) {
11118 Slog.d(TAG, "Resolved nativeLibraryRoot for " + parsedPackage.getPackageName()
11119 + " to root=" + parsedPackage.getNativeLibraryRootDir() + ", isa="
11120 + parsedPackage.isNativeLibraryRootRequiresIsa());
11123 // Push the derived path down into PackageSettings so we know what to
11124 // clean up at uninstall time.
11125 pkgSetting.legacyNativeLibraryPathString = parsedPackage.getNativeLibraryRootDir();
11127 if (DEBUG_ABI_SELECTION) {
11128 Log.d(TAG, "Abis for package[" + parsedPackage.getPackageName() + "] are" +
11129 " primary=" + AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage) +
11130 " secondary=" + AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage));
11133 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
11134 // We don't do this here during boot because we can do it all
11135 // at once after scanning all existing packages.
11137 // We also do this *before* we perform dexopt on this package, so that
11138 // we can avoid redundant dexopts, and also to make sure we've got the
11139 // code and package path correct.
11140 changedAbiCodePath = applyAdjustedAbiToSharedUser(pkgSetting.sharedUser, parsedPackage,
11141 packageAbiHelper.getAdjustedAbiForSharedUser(
11142 pkgSetting.sharedUser.packages, parsedPackage));
11145 parsedPackage.setFactoryTest(isUnderFactoryTest && parsedPackage.getRequestedPermissions()
11146 .contains(android.Manifest.permission.FACTORY_TEST));
11148 if (parsedPackage.isSystem()) {
11149 pkgSetting.setIsOrphaned(true);
11152 // Take care of first install / last update times.
11153 final long scanFileTime = getLastModifiedTime(parsedPackage);
11154 if (currentTime != 0) {
11155 if (pkgSetting.firstInstallTime == 0) {
11156 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
11157 } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
11158 pkgSetting.lastUpdateTime = currentTime;
11160 } else if (pkgSetting.firstInstallTime == 0) {
11161 // We need *something*. Take time time stamp of the file.
11162 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
11163 } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
11164 if (scanFileTime != pkgSetting.timeStamp) {
11165 // A package on the system image has changed; consider this
11166 // to be an update.
11167 pkgSetting.lastUpdateTime = scanFileTime;
11170 pkgSetting.setTimeStamp(scanFileTime);
11171 // TODO(b/135203078): Remove, move to constructor
11172 pkgSetting.pkg = parsedPackage;
11173 pkgSetting.pkgFlags = PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting);
11174 pkgSetting.pkgPrivateFlags =
11175 PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting);
11176 if (parsedPackage.getLongVersionCode() != pkgSetting.versionCode) {
11177 pkgSetting.versionCode = parsedPackage.getLongVersionCode();
11179 // Update volume if needed
11180 final String volumeUuid = parsedPackage.getVolumeUuid();
11181 if (!Objects.equals(volumeUuid, pkgSetting.volumeUuid)) {
11182 Slog.i(PackageManagerService.TAG,
11183 "Update" + (pkgSetting.isSystem() ? " system" : "")
11184 + " package " + parsedPackage.getPackageName()
11185 + " volume from " + pkgSetting.volumeUuid
11186 + " to " + volumeUuid);
11187 pkgSetting.volumeUuid = volumeUuid;
11190 SharedLibraryInfo staticSharedLibraryInfo = null;
11191 if (!TextUtils.isEmpty(parsedPackage.getStaticSharedLibName())) {
11192 staticSharedLibraryInfo =
11193 AndroidPackageUtils.createSharedLibraryForStatic(parsedPackage);
11195 List<SharedLibraryInfo> dynamicSharedLibraryInfos = null;
11196 if (!ArrayUtils.isEmpty(parsedPackage.getLibraryNames())) {
11197 dynamicSharedLibraryInfos = new ArrayList<>(parsedPackage.getLibraryNames().size());
11198 for (String name : parsedPackage.getLibraryNames()) {
11199 dynamicSharedLibraryInfos.add(
11200 AndroidPackageUtils.createSharedLibraryForDynamic(parsedPackage, name));
11204 return new ScanResult(request, true, pkgSetting, changedAbiCodePath,
11205 !createNewPackage /* existingSettingCopied */, staticSharedLibraryInfo,
11206 dynamicSharedLibraryInfos);
11210 * Returns {@code true} if the given file contains code. Otherwise {@code false}.
11212 private static boolean apkHasCode(String fileName) {
11213 StrictJarFile jarFile = null;
11215 jarFile = new StrictJarFile(fileName,
11216 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
11217 return jarFile.findEntry("classes.dex") != null;
11218 } catch (IOException ignore) {
11221 if (jarFile != null) {
11224 } catch (IOException ignore) {}
11230 * Enforces code policy for the package. This ensures that if an APK has
11231 * declared hasCode="true" in its manifest that the APK actually contains
11234 * @throws PackageManagerException If bytecode could not be found when it should exist
11236 private static void assertCodePolicy(AndroidPackage pkg)
11237 throws PackageManagerException {
11238 final boolean shouldHaveCode = pkg.isHasCode();
11239 if (shouldHaveCode && !apkHasCode(pkg.getBaseCodePath())) {
11240 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
11241 "Package " + pkg.getBaseCodePath() + " code is missing");
11244 if (!ArrayUtils.isEmpty(pkg.getSplitCodePaths())) {
11245 for (int i = 0; i < pkg.getSplitCodePaths().length; i++) {
11246 final boolean splitShouldHaveCode =
11247 (pkg.getSplitFlags()[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
11248 if (splitShouldHaveCode && !apkHasCode(pkg.getSplitCodePaths()[i])) {
11249 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
11250 "Package " + pkg.getSplitCodePaths()[i] + " code is missing");
11257 * Applies policy to the parsed package based upon the given policy flags.
11258 * Ensures the package is in a good state.
11260 * Implementation detail: This method must NOT have any side effect. It would
11261 * ideally be static, but, it requires locks to read system state.
11263 private static void applyPolicy(ParsedPackage parsedPackage, final @ParseFlags int parseFlags,
11264 final @ScanFlags int scanFlags, AndroidPackage platformPkg,
11265 boolean isUpdatedSystemApp) {
11266 if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
11267 parsedPackage.setSystem(true);
11268 // TODO(b/135203078): Can this be done in PackageParser? Or just inferred when the flag
11269 // is set during parse.
11270 if (parsedPackage.isDirectBootAware()) {
11271 parsedPackage.setAllComponentsDirectBootAware(true);
11273 if (compressedFileExists(parsedPackage.getCodePath())) {
11274 parsedPackage.setStub(true);
11278 // non system apps can't be flagged as core
11280 // clear flags not applicable to regular apps
11281 .setPersistent(false)
11282 .setDefaultToDeviceProtectedStorage(false)
11283 .setDirectBootAware(false)
11284 // non system apps can't have permission priority
11285 .capPermissionPriorities();
11287 if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
11289 .clearProtectedBroadcasts()
11290 .markNotActivitiesAsNotExportedIfSingleUser();
11293 parsedPackage.setPrivileged((scanFlags & SCAN_AS_PRIVILEGED) != 0)
11294 .setOem((scanFlags & SCAN_AS_OEM) != 0)
11295 .setVendor((scanFlags & SCAN_AS_VENDOR) != 0)
11296 .setProduct((scanFlags & SCAN_AS_PRODUCT) != 0)
11297 .setSystemExt((scanFlags & SCAN_AS_SYSTEM_EXT) != 0)
11298 .setOdm((scanFlags & SCAN_AS_ODM) != 0);
11300 // Check if the package is signed with the same key as the platform package.
11301 parsedPackage.setSignedWithPlatformKey(
11302 (PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())
11303 || (platformPkg != null && compareSignatures(
11304 platformPkg.getSigningDetails().signatures,
11305 parsedPackage.getSigningDetails().signatures
11306 ) == PackageManager.SIGNATURE_MATCH))
11309 if (!parsedPackage.isSystem()) {
11310 // Only system apps can use these features.
11311 parsedPackage.clearOriginalPackages()
11312 .setRealPackage(null)
11313 .clearAdoptPermissions();
11316 PackageBackwardCompatibility.modifySharedLibraries(parsedPackage, isUpdatedSystemApp);
11319 private static @NonNull <T> T assertNotNull(@Nullable T object, String message)
11320 throws PackageManagerException {
11321 if (object == null) {
11322 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, message);
11327 private <T extends ParsedMainComponent>
11328 void assertPackageProcesses(AndroidPackage pkg, List<T> components,
11329 Map<String, ParsedProcess> procs, String compName)
11330 throws PackageManagerException {
11331 if (components == null) {
11334 for (int i = components.size() - 1; i >= 0; i--) {
11335 final ParsedMainComponent component = components.get(i);
11336 if (!procs.containsKey(component.getProcessName())) {
11337 throw new PackageManagerException(
11338 INSTALL_FAILED_PROCESS_NOT_DEFINED,
11339 "Can't install because " + compName + " " + component.getClassName()
11340 + "'s process attribute " + component.getProcessName()
11341 + " (in package " + pkg.getPackageName()
11342 + ") is not included in the <processes> list");
11348 * Asserts the parsed package is valid according to the given policy. If the
11349 * package is invalid, for whatever reason, throws {@link PackageManagerException}.
11351 * Implementation detail: This method must NOT have any side effects. It would
11352 * ideally be static, but, it requires locks to read system state.
11354 * @throws PackageManagerException If the package fails any of the validation checks
11356 private void assertPackageIsValid(AndroidPackage pkg, final @ParseFlags int parseFlags,
11357 final @ScanFlags int scanFlags)
11358 throws PackageManagerException {
11359 if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
11360 assertCodePolicy(pkg);
11363 if (pkg.getCodePath() == null) {
11364 // Bail out. The resource and code paths haven't been set.
11365 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
11366 "Code and resource paths haven't been set correctly");
11369 // Check that there is an APEX package with the same name only during install/first boot
11371 final boolean isUserInstall = (scanFlags & SCAN_BOOTING) == 0;
11372 final boolean isFirstBootOrUpgrade = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
11373 if ((isUserInstall || isFirstBootOrUpgrade)
11374 && mApexManager.isApexPackage(pkg.getPackageName())) {
11375 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11376 pkg.getPackageName()
11377 + " is an APEX package and can't be installed as an APK.");
11380 // Make sure we're not adding any bogus keyset info
11381 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
11382 ksms.assertScannedPackageValid(pkg);
11384 synchronized (mLock) {
11385 // The special "android" package can only be defined once
11386 if (pkg.getPackageName().equals("android")) {
11387 if (mAndroidApplication != null) {
11388 Slog.w(TAG, "*************************************************");
11389 Slog.w(TAG, "Core android package being redefined. Skipping.");
11390 Slog.w(TAG, " codePath=" + pkg.getCodePath());
11391 Slog.w(TAG, "*************************************************");
11392 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11393 "Core android package being redefined. Skipping.");
11397 // A package name must be unique; don't allow duplicates
11398 if ((scanFlags & SCAN_NEW_INSTALL) == 0
11399 && mPackages.containsKey(pkg.getPackageName())) {
11400 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11401 "Application package " + pkg.getPackageName()
11402 + " already installed. Skipping duplicate.");
11405 if (pkg.isStaticSharedLibrary()) {
11406 // Static libs have a synthetic package name containing the version
11407 // but we still want the base name to be unique.
11408 if ((scanFlags & SCAN_NEW_INSTALL) == 0
11409 && mPackages.containsKey(pkg.getManifestPackageName())) {
11410 throw new PackageManagerException(
11411 "Duplicate static shared lib provider package");
11414 // Static shared libraries should have at least O target SDK
11415 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
11416 throw new PackageManagerException(
11417 "Packages declaring static-shared libs must target O SDK or higher");
11420 // Package declaring static a shared lib cannot be instant apps
11421 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11422 throw new PackageManagerException(
11423 "Packages declaring static-shared libs cannot be instant apps");
11426 // Package declaring static a shared lib cannot be renamed since the package
11427 // name is synthetic and apps can't code around package manager internals.
11428 if (!ArrayUtils.isEmpty(pkg.getOriginalPackages())) {
11429 throw new PackageManagerException(
11430 "Packages declaring static-shared libs cannot be renamed");
11433 // Package declaring static a shared lib cannot declare dynamic libs
11434 if (!ArrayUtils.isEmpty(pkg.getLibraryNames())) {
11435 throw new PackageManagerException(
11436 "Packages declaring static-shared libs cannot declare dynamic libs");
11439 // Package declaring static a shared lib cannot declare shared users
11440 if (pkg.getSharedUserId() != null) {
11441 throw new PackageManagerException(
11442 "Packages declaring static-shared libs cannot declare shared users");
11445 // Static shared libs cannot declare activities
11446 if (!pkg.getActivities().isEmpty()) {
11447 throw new PackageManagerException(
11448 "Static shared libs cannot declare activities");
11451 // Static shared libs cannot declare services
11452 if (!pkg.getServices().isEmpty()) {
11453 throw new PackageManagerException(
11454 "Static shared libs cannot declare services");
11457 // Static shared libs cannot declare providers
11458 if (!pkg.getProviders().isEmpty()) {
11459 throw new PackageManagerException(
11460 "Static shared libs cannot declare content providers");
11463 // Static shared libs cannot declare receivers
11464 if (!pkg.getReceivers().isEmpty()) {
11465 throw new PackageManagerException(
11466 "Static shared libs cannot declare broadcast receivers");
11469 // Static shared libs cannot declare permission groups
11470 if (!pkg.getPermissionGroups().isEmpty()) {
11471 throw new PackageManagerException(
11472 "Static shared libs cannot declare permission groups");
11475 // Static shared libs cannot declare features
11476 if (!pkg.getFeatures().isEmpty()) {
11477 throw new PackageManagerException(
11478 "Static shared libs cannot declare features");
11481 // Static shared libs cannot declare permissions
11482 if (!pkg.getPermissions().isEmpty()) {
11483 throw new PackageManagerException(
11484 "Static shared libs cannot declare permissions");
11487 // Static shared libs cannot declare protected broadcasts
11488 if (!pkg.getProtectedBroadcasts().isEmpty()) {
11489 throw new PackageManagerException(
11490 "Static shared libs cannot declare protected broadcasts");
11493 // Static shared libs cannot be overlay targets
11494 if (pkg.getOverlayTarget() != null) {
11495 throw new PackageManagerException(
11496 "Static shared libs cannot be overlay targets");
11499 // The version codes must be ordered as lib versions
11500 long minVersionCode = Long.MIN_VALUE;
11501 long maxVersionCode = Long.MAX_VALUE;
11503 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(
11504 pkg.getStaticSharedLibName());
11505 if (versionedLib != null) {
11506 final int versionCount = versionedLib.size();
11507 for (int i = 0; i < versionCount; i++) {
11508 SharedLibraryInfo libInfo = versionedLib.valueAt(i);
11509 final long libVersionCode = libInfo.getDeclaringPackage()
11510 .getLongVersionCode();
11511 if (libInfo.getLongVersion() < pkg.getStaticSharedLibVersion()) {
11512 minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
11513 } else if (libInfo.getLongVersion()
11514 > pkg.getStaticSharedLibVersion()) {
11515 maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
11517 minVersionCode = maxVersionCode = libVersionCode;
11522 if (pkg.getLongVersionCode() < minVersionCode
11523 || pkg.getLongVersionCode() > maxVersionCode) {
11524 throw new PackageManagerException("Static shared"
11525 + " lib version codes must be ordered as lib versions");
11529 // If we're only installing presumed-existing packages, require that the
11530 // scanned APK is both already known and at the path previously established
11531 // for it. Previously unknown packages we pick up normally, but if we have an
11532 // a priori expectation about this package's install presence, enforce it.
11533 // With a singular exception for new system packages. When an OTA contains
11534 // a new system package, we allow the codepath to change from a system location
11535 // to the user-installed location. If we don't allow this change, any newer,
11536 // user-installed version of the application will be ignored.
11537 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
11538 if (mExpectingBetter.containsKey(pkg.getPackageName())) {
11539 logCriticalInfo(Log.WARN,
11540 "Relax SCAN_REQUIRE_KNOWN requirement for package "
11541 + pkg.getPackageName());
11543 PackageSetting known = mSettings.getPackageLPr(pkg.getPackageName());
11544 if (known != null) {
11545 if (DEBUG_PACKAGE_SCANNING) {
11546 Log.d(TAG, "Examining " + pkg.getCodePath()
11547 + " and requiring known paths " + known.codePathString
11548 + " & " + known.resourcePathString);
11550 if (!pkg.getCodePath().equals(known.codePathString)
11551 || !pkg.getCodePath().equals(known.resourcePathString)) {
11552 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
11553 "Application package " + pkg.getPackageName()
11554 + " found at " + pkg.getCodePath()
11555 + " but expected at " + known.codePathString
11559 throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
11560 "Application package " + pkg.getPackageName()
11561 + " not found; ignoring.");
11566 // Verify that this new package doesn't have any content providers
11567 // that conflict with existing packages. Only do this if the
11568 // package isn't already installed, since we don't want to break
11569 // things that are installed.
11570 if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
11571 mComponentResolver.assertProvidersNotDefined(pkg);
11574 // If this package has defined explicit processes, then ensure that these are
11575 // the only processes used by its components.
11576 final Map<String, ParsedProcess> procs = pkg.getProcesses();
11577 if (!procs.isEmpty()) {
11578 if (!procs.containsKey(pkg.getProcessName())) {
11579 throw new PackageManagerException(
11580 INSTALL_FAILED_PROCESS_NOT_DEFINED,
11581 "Can't install because application tag's process attribute "
11582 + pkg.getProcessName()
11583 + " (in package " + pkg.getPackageName()
11584 + ") is not included in the <processes> list");
11586 assertPackageProcesses(pkg, pkg.getActivities(), procs, "activity");
11587 assertPackageProcesses(pkg, pkg.getServices(), procs, "service");
11588 assertPackageProcesses(pkg, pkg.getReceivers(), procs, "receiver");
11589 assertPackageProcesses(pkg, pkg.getProviders(), procs, "provider");
11592 // Verify that packages sharing a user with a privileged app are marked as privileged.
11593 if (!pkg.isPrivileged() && (pkg.getSharedUserId() != null)) {
11594 SharedUserSetting sharedUserSetting = null;
11596 sharedUserSetting = mSettings.getSharedUserLPw(pkg.getSharedUserId(),
11598 } catch (PackageManagerException ignore) {
11600 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
11601 // Exempt SharedUsers signed with the platform key.
11602 PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
11603 if ((platformPkgSetting.signatures.mSigningDetails
11604 != PackageParser.SigningDetails.UNKNOWN)
11605 && (compareSignatures(
11606 platformPkgSetting.signatures.mSigningDetails.signatures,
11607 pkg.getSigningDetails().signatures)
11608 != PackageManager.SIGNATURE_MATCH)) {
11609 throw new PackageManagerException("Apps that share a user with a " +
11610 "privileged app must themselves be marked as privileged. " +
11611 pkg.getPackageName() + " shares privileged user " +
11612 pkg.getSharedUserId() + ".");
11617 // Apply policies specific for runtime resource overlays (RROs).
11618 if (pkg.getOverlayTarget() != null) {
11619 // System overlays have some restrictions on their use of the 'static' state.
11620 if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
11621 // We are scanning a system overlay. This can be the first scan of the
11622 // system/vendor/oem partition, or an update to the system overlay.
11623 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11624 // This must be an update to a system overlay. Immutable overlays cannot be
11626 Objects.requireNonNull(mOverlayConfig,
11627 "Parsing non-system dir before overlay configs are initialized");
11628 if (!mOverlayConfig.isMutable(pkg.getPackageName())) {
11629 throw new PackageManagerException("Overlay "
11630 + pkg.getPackageName()
11631 + " is static and cannot be upgraded.");
11635 // A non-preloaded overlay packages must have targetSdkVersion >= Q, or be
11636 // signed with the platform certificate. Check this in increasing order of
11637 // computational cost.
11638 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.Q) {
11639 final PackageSetting platformPkgSetting =
11640 mSettings.getPackageLPr("android");
11641 if ((platformPkgSetting.signatures.mSigningDetails
11642 != PackageParser.SigningDetails.UNKNOWN)
11643 && (compareSignatures(
11644 platformPkgSetting.signatures.mSigningDetails.signatures,
11645 pkg.getSigningDetails().signatures)
11646 != PackageManager.SIGNATURE_MATCH)) {
11647 throw new PackageManagerException("Overlay "
11648 + pkg.getPackageName()
11649 + " must target Q or later, "
11650 + "or be signed with the platform certificate");
11654 // A non-preloaded overlay package, without <overlay android:targetName>, will
11655 // only be used if it is signed with the same certificate as its target. If the
11656 // target is already installed, check this here to augment the last line of
11657 // defence which is OMS.
11658 if (pkg.getOverlayTargetName() == null) {
11659 final PackageSetting targetPkgSetting =
11660 mSettings.getPackageLPr(pkg.getOverlayTarget());
11661 if (targetPkgSetting != null) {
11662 if ((targetPkgSetting.signatures.mSigningDetails
11663 != PackageParser.SigningDetails.UNKNOWN)
11664 && (compareSignatures(
11665 targetPkgSetting.signatures.mSigningDetails.signatures,
11666 pkg.getSigningDetails().signatures)
11667 != PackageManager.SIGNATURE_MATCH)) {
11668 throw new PackageManagerException("Overlay "
11669 + pkg.getPackageName() + " and target "
11670 + pkg.getOverlayTarget() + " signed with"
11671 + " different certificates, and the overlay lacks"
11672 + " <overlay android:targetName>");
11679 // Ensure the package is signed with at least the minimum signature scheme version
11680 // required for its target SDK.
11681 int minSignatureSchemeVersion =
11682 ApkSignatureVerifier.getMinimumSignatureSchemeVersionForTargetSdk(
11683 pkg.getTargetSdkVersion());
11684 if (pkg.getSigningDetails().signatureSchemeVersion < minSignatureSchemeVersion) {
11685 throw new PackageManagerException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
11686 "No signature found in package of version " + minSignatureSchemeVersion
11687 + " or newer for package " + pkg.getPackageName());
11692 @GuardedBy("mLock")
11693 private boolean addBuiltInSharedLibraryLocked(String path, String name) {
11694 if (nonStaticSharedLibExistsLocked(name)) {
11698 SharedLibraryInfo libraryInfo = new SharedLibraryInfo(path, null, null, name,
11699 (long) SharedLibraryInfo.VERSION_UNDEFINED, SharedLibraryInfo.TYPE_BUILTIN,
11700 new VersionedPackage(PLATFORM_PACKAGE_NAME, (long) 0),
11703 commitSharedLibraryInfoLocked(libraryInfo);
11707 @GuardedBy("mLock")
11708 private boolean nonStaticSharedLibExistsLocked(String name) {
11709 return sharedLibExists(name, SharedLibraryInfo.VERSION_UNDEFINED, mSharedLibraries);
11712 private static boolean sharedLibExists(final String name, final long version,
11713 Map<String, LongSparseArray<SharedLibraryInfo>> librarySource) {
11714 LongSparseArray<SharedLibraryInfo> versionedLib = librarySource.get(name);
11715 if (versionedLib != null && versionedLib.indexOfKey(version) >= 0) {
11721 @GuardedBy("mLock")
11722 private void commitSharedLibraryInfoLocked(SharedLibraryInfo libraryInfo) {
11723 final String name = libraryInfo.getName();
11724 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(name);
11725 if (versionedLib == null) {
11726 versionedLib = new LongSparseArray<>();
11727 mSharedLibraries.put(name, versionedLib);
11729 final String declaringPackageName = libraryInfo.getDeclaringPackage().getPackageName();
11730 if (libraryInfo.getType() == SharedLibraryInfo.TYPE_STATIC) {
11731 mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
11733 versionedLib.put(libraryInfo.getLongVersion(), libraryInfo);
11736 private boolean removeSharedLibraryLPw(String name, long version) {
11737 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(name);
11738 if (versionedLib == null) {
11741 final int libIdx = versionedLib.indexOfKey(version);
11745 SharedLibraryInfo libraryInfo = versionedLib.valueAt(libIdx);
11747 // Remove the shared library overlays from its dependent packages.
11748 for (int currentUserId : UserManagerService.getInstance().getUserIds()) {
11749 final List<VersionedPackage> dependents = getPackagesUsingSharedLibraryLPr(
11750 libraryInfo, 0, currentUserId);
11751 if (dependents == null) {
11754 for (VersionedPackage dependentPackage : dependents) {
11755 final PackageSetting ps = mSettings.mPackages.get(
11756 dependentPackage.getPackageName());
11758 ps.setOverlayPathsForLibrary(libraryInfo.getName(), null, currentUserId);
11763 versionedLib.remove(version);
11764 if (versionedLib.size() <= 0) {
11765 mSharedLibraries.remove(name);
11766 if (libraryInfo.getType() == SharedLibraryInfo.TYPE_STATIC) {
11767 mStaticLibsByDeclaringPackage.remove(libraryInfo.getDeclaringPackage()
11768 .getPackageName());
11775 * Adds a scanned package to the system. When this method is finished, the package will
11776 * be available for query, resolution, etc...
11778 private void commitPackageSettings(AndroidPackage pkg,
11779 @Nullable AndroidPackage oldPkg, PackageSetting pkgSetting,
11780 final @ScanFlags int scanFlags, boolean chatty, ReconciledPackage reconciledPkg) {
11781 final String pkgName = pkg.getPackageName();
11782 if (mCustomResolverComponentName != null &&
11783 mCustomResolverComponentName.getPackageName().equals(pkg.getPackageName())) {
11784 setUpCustomResolverActivity(pkg);
11787 if (pkg.getPackageName().equals("android")) {
11788 synchronized (mLock) {
11789 // Set up information for our fall-back user intent resolution activity.
11790 mPlatformPackage = pkg;
11791 mAndroidApplication = pkg.toAppInfoWithoutState();
11792 if (!mResolverReplaced) {
11793 mResolveActivity.applicationInfo = mAndroidApplication;
11794 mResolveActivity.name = ResolverActivity.class.getName();
11795 mResolveActivity.packageName = mAndroidApplication.packageName;
11796 mResolveActivity.processName = "system:ui";
11797 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11798 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
11799 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
11800 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
11801 mResolveActivity.exported = true;
11802 mResolveActivity.enabled = true;
11803 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
11804 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
11805 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
11806 | ActivityInfo.CONFIG_SCREEN_LAYOUT
11807 | ActivityInfo.CONFIG_ORIENTATION
11808 | ActivityInfo.CONFIG_KEYBOARD
11809 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
11810 mResolveInfo.activityInfo = mResolveActivity;
11811 mResolveInfo.priority = 0;
11812 mResolveInfo.preferredOrder = 0;
11813 mResolveInfo.match = 0;
11814 mResolveComponentName = new ComponentName(
11815 mAndroidApplication.packageName, mResolveActivity.name);
11820 ArrayList<AndroidPackage> clientLibPkgs = null;
11822 synchronized (mLock) {
11823 if (!ArrayUtils.isEmpty(reconciledPkg.allowedSharedLibraryInfos)) {
11824 for (SharedLibraryInfo info : reconciledPkg.allowedSharedLibraryInfos) {
11825 commitSharedLibraryInfoLocked(info);
11827 final Map<String, AndroidPackage> combinedSigningDetails =
11828 reconciledPkg.getCombinedAvailablePackages();
11830 // Shared libraries for the package need to be updated.
11831 updateSharedLibrariesLocked(pkg, pkgSetting, null, null,
11832 combinedSigningDetails);
11833 } catch (PackageManagerException e) {
11834 Slog.e(TAG, "updateSharedLibrariesLPr failed: ", e);
11836 // Update all applications that use this library. Skip when booting
11837 // since this will be done after all packages are scaned.
11838 if ((scanFlags & SCAN_BOOTING) == 0) {
11839 clientLibPkgs = updateAllSharedLibrariesLocked(pkg, pkgSetting,
11840 combinedSigningDetails);
11844 if (reconciledPkg.installResult != null) {
11845 reconciledPkg.installResult.libraryConsumers = clientLibPkgs;
11848 if ((scanFlags & SCAN_BOOTING) != 0) {
11849 // No apps can run during boot scan, so they don't need to be frozen
11850 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
11851 // Caller asked to not kill app, so it's probably not frozen
11852 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
11853 // Caller asked us to ignore frozen check for some reason; they
11854 // probably didn't know the package name
11856 // We're doing major surgery on this package, so it better be frozen
11857 // right now to keep it from launching
11858 checkPackageFrozen(pkgName);
11861 // Also need to kill any apps that are dependent on the library.
11862 if (clientLibPkgs != null) {
11863 for (int i=0; i<clientLibPkgs.size(); i++) {
11864 AndroidPackage clientPkg = clientLibPkgs.get(i);
11865 killApplication(clientPkg.getPackageName(),
11866 clientPkg.getUid(), "update lib");
11871 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11873 synchronized (mLock) {
11874 // We don't expect installation to fail beyond this point
11876 // Add the new setting to mSettings
11877 mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11878 // Add the new setting to mPackages
11879 mPackages.put(pkg.getPackageName(), pkg);
11880 if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
11881 mApexManager.registerApkInApex(pkg);
11884 // Add the package's KeySets to the global KeySetManagerService
11885 KeySetManagerService ksms = mSettings.mKeySetManagerService;
11886 ksms.addScannedPackageLPw(pkg);
11888 mComponentResolver.addAllComponents(pkg, chatty);
11889 mAppsFilter.addPackage(pkgSetting, mSettings.mPackages);
11891 // Don't allow ephemeral applications to define new permissions groups.
11892 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11893 Slog.w(TAG, "Permission groups from package " + pkg.getPackageName()
11894 + " ignored: instant apps cannot define new permission groups.");
11896 mPermissionManager.addAllPermissionGroups(pkg, chatty);
11899 // Don't allow ephemeral applications to define new permissions.
11900 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11901 Slog.w(TAG, "Permissions from package " + pkg.getPackageName()
11902 + " ignored: instant apps cannot define new permissions.");
11904 mPermissionManager.addAllPermissions(pkg, chatty);
11907 int collectionSize = ArrayUtils.size(pkg.getInstrumentations());
11908 StringBuilder r = null;
11910 for (i = 0; i < collectionSize; i++) {
11911 ParsedInstrumentation a = pkg.getInstrumentations().get(i);
11912 a.setPackageName(pkg.getPackageName());
11913 mInstrumentation.put(a.getComponentName(), a);
11916 r = new StringBuilder(256);
11920 r.append(a.getName());
11924 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r);
11927 if (!pkg.getProtectedBroadcasts().isEmpty()) {
11928 synchronized (mProtectedBroadcasts) {
11929 mProtectedBroadcasts.addAll(pkg.getProtectedBroadcasts());
11933 if (oldPkg != null) {
11934 // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
11935 // revoke callbacks from this method might need to kill apps which need the
11936 // mPackages lock on a different thread. This would dead lock.
11938 // Hence create a copy of all package names and pass it into
11939 // revokeRuntimePermissionsIfGroupChanged. Only for those permissions might get
11940 // revoked. If a new package is added before the async code runs the permission
11941 // won't be granted yet, hence new packages are no problem.
11942 final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
11944 AsyncTask.execute(() ->
11945 mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg,
11950 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11953 private void setUpCustomResolverActivity(AndroidPackage pkg) {
11954 synchronized (mLock) {
11955 mResolverReplaced = true;
11956 // Set up information for custom user intent resolution activity.
11957 mResolveActivity.applicationInfo = pkg.toAppInfoWithoutState();
11958 mResolveActivity.name = mCustomResolverComponentName.getClassName();
11959 mResolveActivity.packageName = pkg.getPackageName();
11960 mResolveActivity.processName = pkg.getProcessName();
11961 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11962 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11963 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11964 mResolveActivity.theme = 0;
11965 mResolveActivity.exported = true;
11966 mResolveActivity.enabled = true;
11967 mResolveInfo.activityInfo = mResolveActivity;
11968 mResolveInfo.priority = 0;
11969 mResolveInfo.preferredOrder = 0;
11970 mResolveInfo.match = 0;
11971 mResolveComponentName = mCustomResolverComponentName;
11972 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11973 mResolveComponentName);
11977 private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11978 if (installerActivity == null) {
11979 if (DEBUG_INSTANT) {
11980 Slog.d(TAG, "Clear ephemeral installer activity");
11982 mInstantAppInstallerActivity = null;
11986 if (DEBUG_INSTANT) {
11987 Slog.d(TAG, "Set ephemeral installer activity: "
11988 + installerActivity.getComponentName());
11990 // Set up information for ephemeral installer activity
11991 mInstantAppInstallerActivity = installerActivity;
11992 mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
11993 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11994 mInstantAppInstallerActivity.exported = true;
11995 mInstantAppInstallerActivity.enabled = true;
11996 mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
11997 mInstantAppInstallerInfo.priority = 1;
11998 mInstantAppInstallerInfo.preferredOrder = 1;
11999 mInstantAppInstallerInfo.isDefault = true;
12000 mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
12001 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
12004 private void killApplication(String pkgName, @AppIdInt int appId, String reason) {
12005 killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
12008 private void killApplication(String pkgName, @AppIdInt int appId,
12009 @UserIdInt int userId, String reason) {
12010 // Request the ActivityManager to kill the process(only for existing packages)
12011 // so that we do not end up in a confused state while the user is still using the older
12012 // version of the application while the new one gets installed.
12013 final long token = Binder.clearCallingIdentity();
12015 IActivityManager am = ActivityManager.getService();
12018 am.killApplication(pkgName, appId, userId, reason);
12019 } catch (RemoteException e) {
12023 Binder.restoreCallingIdentity(token);
12027 private void removePackageLI(AndroidPackage pkg, boolean chatty) {
12028 // Remove the parent package setting
12029 PackageSetting ps = getPackageSetting(pkg.getPackageName());
12031 removePackageLI(ps.name, chatty);
12032 } else if (DEBUG_REMOVE && chatty) {
12033 Log.d(TAG, "Not removing package " + pkg.getPackageName() + "; mExtras == null");
12037 void removePackageLI(String packageName, boolean chatty) {
12038 if (DEBUG_INSTALL) {
12040 Log.d(TAG, "Removing package " + packageName);
12044 synchronized (mLock) {
12045 final AndroidPackage removedPackage = mPackages.remove(packageName);
12046 if (removedPackage != null) {
12047 cleanPackageDataStructuresLILPw(removedPackage, chatty);
12052 void cleanPackageDataStructuresLILPw(AndroidPackage pkg, boolean chatty) {
12053 mComponentResolver.removeAllComponents(pkg, chatty);
12054 mAppsFilter.removePackage(getPackageSetting(pkg.getPackageName()),
12055 mInjector.getUserManagerInternal().getUserIds(), mSettings.mPackages);
12056 mPermissionManager.removeAllPermissions(pkg, chatty);
12058 final int instrumentationSize = ArrayUtils.size(pkg.getInstrumentations());
12059 StringBuilder r = null;
12061 for (i = 0; i < instrumentationSize; i++) {
12062 ParsedInstrumentation a = pkg.getInstrumentations().get(i);
12063 mInstrumentation.remove(a.getComponentName());
12064 if (DEBUG_REMOVE && chatty) {
12066 r = new StringBuilder(256);
12070 r.append(a.getName());
12074 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
12078 if (pkg.isSystem()) {
12079 // Only system apps can hold shared libraries.
12080 final int libraryNamesSize = pkg.getLibraryNames().size();
12081 for (i = 0; i < libraryNamesSize; i++) {
12082 String name = pkg.getLibraryNames().get(i);
12083 if (removeSharedLibraryLPw(name, 0)) {
12084 if (DEBUG_REMOVE && chatty) {
12086 r = new StringBuilder(256);
12098 // Any package can hold static shared libraries.
12099 if (pkg.getStaticSharedLibName() != null) {
12100 if (removeSharedLibraryLPw(pkg.getStaticSharedLibName(),
12101 pkg.getStaticSharedLibVersion())) {
12102 if (DEBUG_REMOVE && chatty) {
12104 r = new StringBuilder(256);
12108 r.append(pkg.getStaticSharedLibName());
12114 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r);
12119 public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
12120 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
12121 final int[] userIds, int[] instantUserIds) {
12122 mHandler.post(() -> {
12124 final IActivityManager am = ActivityManager.getService();
12125 if (am == null) return;
12126 final int[] resolvedUserIds;
12127 if (userIds == null) {
12128 resolvedUserIds = am.getRunningUserIds();
12130 resolvedUserIds = userIds;
12132 doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
12133 resolvedUserIds, false);
12134 if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
12135 doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
12136 instantUserIds, true);
12138 } catch (RemoteException ex) {
12144 public void notifyPackageAdded(String packageName, int uid) {
12145 final PackageListObserver[] observers;
12146 synchronized (mLock) {
12147 if (mPackageListObservers.size() == 0) {
12150 final PackageListObserver[] observerArray =
12151 new PackageListObserver[mPackageListObservers.size()];
12152 observers = mPackageListObservers.toArray(observerArray);
12154 for (int i = observers.length - 1; i >= 0; --i) {
12155 observers[i].onPackageAdded(packageName, uid);
12160 public void notifyPackageChanged(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].onPackageChanged(packageName, uid);
12175 private static final Comparator<ProviderInfo> sProviderInitOrderSorter = (p1, p2) -> {
12176 final int v1 = p1.initOrder;
12177 final int v2 = p2.initOrder;
12178 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
12182 public void notifyPackageRemoved(String packageName, int uid) {
12183 final PackageListObserver[] observers;
12184 synchronized (mLock) {
12185 if (mPackageListObservers.size() == 0) {
12188 final PackageListObserver[] observerArray =
12189 new PackageListObserver[mPackageListObservers.size()];
12190 observers = mPackageListObservers.toArray(observerArray);
12192 for (int i = observers.length - 1; i >= 0; --i) {
12193 observers[i].onPackageRemoved(packageName, uid);
12198 * Sends a broadcast for the given action.
12199 * <p>If {@code isInstantApp} is {@code true}, then the broadcast is protected with
12200 * the {@link android.Manifest.permission#ACCESS_INSTANT_APPS} permission. This allows
12201 * the system and applications allowed to see instant applications to receive package
12202 * lifecycle events for instant applications.
12204 private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
12205 int flags, String targetPkg, IIntentReceiver finishedReceiver,
12206 int[] userIds, boolean isInstantApp)
12207 throws RemoteException {
12208 for (int id : userIds) {
12209 final Intent intent = new Intent(action,
12210 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
12211 final String[] requiredPermissions =
12212 isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null;
12213 if (extras != null) {
12214 intent.putExtras(extras);
12216 if (targetPkg != null) {
12217 intent.setPackage(targetPkg);
12219 // Modify the UID when posting to other users
12220 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
12221 if (uid > 0 && UserHandle.getUserId(uid) != id) {
12222 uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
12223 intent.putExtra(Intent.EXTRA_UID, uid);
12225 intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
12226 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
12227 if (DEBUG_BROADCASTS) {
12228 RuntimeException here = new RuntimeException("here");
12229 here.fillInStackTrace();
12230 Slog.d(TAG, "Sending to user " + id + ": "
12231 + intent.toShortString(false, true, false, false)
12232 + " " + intent.getExtras(), here);
12234 am.broadcastIntentWithFeature(null, null, intent, null, finishedReceiver,
12235 0, null, null, requiredPermissions, android.app.AppOpsManager.OP_NONE,
12236 null, finishedReceiver != null, false, id);
12241 * Check if the external storage media is available. This is true if there
12242 * is a mounted external storage medium or if the external storage is
12245 private boolean isExternalMediaAvailable() {
12246 return mMediaMounted || Environment.isExternalStorageEmulated();
12250 * Ensure that the install reason matches what we know about the package installer (e.g. whether
12251 * it is acting on behalf on an enterprise or the user).
12253 * Note that the ordering of the conditionals in this method is important. The checks we perform
12254 * are as follows, in this order:
12256 * 1) If the install is being performed by a system app, we can trust the app to have set the
12257 * install reason correctly. Thus, we pass through the install reason unchanged, no matter
12259 * 2) If the install is being performed by a device or profile owner app, the install reason
12260 * should be enterprise policy. However, we cannot be sure that the device or profile owner
12261 * set the install reason correctly. If the app targets an older SDK version where install
12262 * reasons did not exist yet, or if the app author simply forgot, the install reason may be
12263 * unset or wrong. Thus, we force the install reason to be enterprise policy.
12264 * 3) In all other cases, the install is being performed by a regular app that is neither part
12265 * of the system nor a device or profile owner. We have no reason to believe that this app is
12266 * acting on behalf of the enterprise admin. Thus, we check whether the install reason was
12267 * set to enterprise policy and if so, change it to unknown instead.
12269 private int fixUpInstallReason(String installerPackageName, int installerUid,
12270 int installReason) {
12271 if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
12272 == PERMISSION_GRANTED) {
12273 // If the install is being performed by a system app, we trust that app to have set the
12274 // install reason correctly.
12275 return installReason;
12277 final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(
12278 UserHandle.getUserId(installerUid));
12279 if (ownerPackage != null && ownerPackage.equals(installerPackageName)) {
12280 // If the install is being performed by a device or profile owner, the install
12281 // reason should be enterprise policy.
12282 return PackageManager.INSTALL_REASON_POLICY;
12286 if (installReason == PackageManager.INSTALL_REASON_POLICY) {
12287 // If the install is being performed by a regular app (i.e. neither system app nor
12288 // device or profile owner), we have no reason to believe that the app is acting on
12289 // behalf of an enterprise. If the app set the install reason to enterprise policy,
12290 // change it to unknown instead.
12291 return PackageManager.INSTALL_REASON_UNKNOWN;
12294 // If the install is being performed by a regular app and the install reason was set to any
12295 // value but enterprise policy, leave the install reason unchanged.
12296 return installReason;
12299 void installStage(ActiveInstallSession activeInstallSession) {
12300 if (DEBUG_INSTANT) {
12301 if ((activeInstallSession.getSessionParams().installFlags
12302 & PackageManager.INSTALL_INSTANT_APP) != 0) {
12303 Slog.d(TAG, "Ephemeral install of " + activeInstallSession.getPackageName());
12306 final Message msg = mHandler.obtainMessage(INIT_COPY);
12307 final InstallParams params = new InstallParams(activeInstallSession);
12308 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
12311 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
12312 System.identityHashCode(msg.obj));
12313 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
12314 System.identityHashCode(msg.obj));
12316 mHandler.sendMessage(msg);
12319 void installStage(List<ActiveInstallSession> children)
12320 throws PackageManagerException {
12321 final Message msg = mHandler.obtainMessage(INIT_COPY);
12322 final MultiPackageInstallParams params =
12323 new MultiPackageInstallParams(UserHandle.ALL, children);
12324 params.setTraceMethod("installStageMultiPackage")
12325 .setTraceCookie(System.identityHashCode(params));
12328 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStageMultiPackage",
12329 System.identityHashCode(msg.obj));
12330 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
12331 System.identityHashCode(msg.obj));
12332 mHandler.sendMessage(msg);
12335 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
12337 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
12338 final boolean isInstantApp = pkgSetting.getInstantApp(userId);
12339 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
12340 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
12341 sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
12342 false /*startReceiver*/, pkgSetting.appId, userIds, instantUserIds);
12344 // Send a session commit broadcast
12345 final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
12346 info.installReason = pkgSetting.getInstallReason(userId);
12347 info.appPackageName = packageName;
12348 sendSessionCommitBroadcast(info, userId);
12352 public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
12353 boolean includeStopped, @AppIdInt int appId, int[] userIds, int[] instantUserIds) {
12354 if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
12357 Bundle extras = new Bundle(1);
12358 // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
12359 final int uid = UserHandle.getUid(
12360 (ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId);
12361 extras.putInt(Intent.EXTRA_UID, uid);
12363 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
12364 packageName, extras, 0, null, null, userIds, instantUserIds);
12365 if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
12366 mHandler.post(() -> {
12367 for (int userId : userIds) {
12368 sendBootCompletedBroadcastToSystemApp(
12369 packageName, includeStopped, userId);
12377 * The just-installed/enabled app is bundled on the system, so presumed to be able to run
12378 * automatically without needing an explicit launch.
12379 * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
12381 private void sendBootCompletedBroadcastToSystemApp(
12382 String packageName, boolean includeStopped, int userId) {
12383 // If user is not running, the app didn't miss any broadcast
12384 if (!mUserManager.isUserRunning(userId)) {
12387 final IActivityManager am = ActivityManager.getService();
12389 // Deliver LOCKED_BOOT_COMPLETED first
12390 Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
12391 .setPackage(packageName);
12392 if (includeStopped) {
12393 lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
12395 final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
12396 am.broadcastIntentWithFeature(null, null, lockedBcIntent, null, null, 0, null, null,
12397 requiredPermissions, android.app.AppOpsManager.OP_NONE, null, false, false,
12400 // Deliver BOOT_COMPLETED only if user is unlocked
12401 if (mUserManager.isUserUnlockingOrUnlocked(userId)) {
12402 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
12403 if (includeStopped) {
12404 bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
12406 am.broadcastIntentWithFeature(null, null, bcIntent, null, null, 0, null, null,
12407 requiredPermissions, android.app.AppOpsManager.OP_NONE, null, false, false,
12410 } catch (RemoteException e) {
12411 throw e.rethrowFromSystemServer();
12416 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
12418 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
12419 PackageSetting pkgSetting;
12420 final int callingUid = Binder.getCallingUid();
12421 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
12422 true /* requireFullPermission */, true /* checkShell */,
12423 "setApplicationHiddenSetting for user " + userId);
12425 if (hidden && isPackageDeviceAdmin(packageName, userId)) {
12426 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
12430 long callingId = Binder.clearCallingIdentity();
12432 boolean sendAdded = false;
12433 boolean sendRemoved = false;
12435 synchronized (mLock) {
12436 pkgSetting = mSettings.mPackages.get(packageName);
12437 if (pkgSetting == null) {
12440 if (shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
12443 // Do not allow "android" is being disabled
12444 if ("android".equals(packageName)) {
12445 Slog.w(TAG, "Cannot hide package: android");
12448 // Cannot hide static shared libs as they are considered
12449 // a part of the using app (emulating static linking). Also
12450 // static libs are installed always on internal storage.
12451 AndroidPackage pkg = mPackages.get(packageName);
12452 if (pkg != null && pkg.getStaticSharedLibName() != null) {
12453 Slog.w(TAG, "Cannot hide package: " + packageName
12454 + " providing static shared library: "
12455 + pkg.getStaticSharedLibName());
12458 // Only allow protected packages to hide themselves.
12459 if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
12460 && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
12461 Slog.w(TAG, "Not hiding protected package: " + packageName);
12465 if (pkgSetting.getHidden(userId) != hidden) {
12466 pkgSetting.setHidden(hidden, userId);
12467 mSettings.writePackageRestrictionsLPr(userId);
12469 sendRemoved = true;
12476 sendPackageAddedForUser(packageName, pkgSetting, userId);
12480 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
12482 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
12486 Binder.restoreCallingIdentity(callingId);
12492 public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) {
12493 final int callingUid = Binder.getCallingUid();
12494 PackageManagerServiceUtils
12495 .enforceSystemOrPhoneCaller("setSystemAppHiddenUntilInstalled", callingUid);
12496 synchronized (mLock) {
12497 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
12498 if (pkgSetting == null || !pkgSetting.isSystem()) {
12501 pkgSetting.getPkgState().setHiddenUntilInstalled(hidden);
12502 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(packageName);
12503 if (disabledPs == null) {
12506 disabledPs.getPkgState().setHiddenUntilInstalled(hidden);
12511 public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
12512 final int callingUid = Binder.getCallingUid();
12513 PackageManagerServiceUtils
12514 .enforceSystemOrPhoneCaller("setSystemAppInstallState", callingUid);
12515 synchronized (mLock) {
12516 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
12517 // The target app should always be in system
12518 if (pkgSetting == null || !pkgSetting.isSystem()) {
12521 // Check if the install state is the same
12522 if (pkgSetting.getInstalled(userId) == installed) {
12527 final long callingId = Binder.clearCallingIdentity();
12530 // install the app from uninstalled state
12531 installExistingPackageAsUser(
12534 PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
12535 PackageManager.INSTALL_REASON_DEVICE_SETUP,
12540 // uninstall the app from installed state
12541 deletePackageVersioned(
12542 new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
12543 new LegacyPackageDeleteObserver(null).getBinder(),
12545 PackageManager.DELETE_SYSTEM_APP);
12548 Binder.restoreCallingIdentity(callingId);
12552 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
12554 final PackageRemovedInfo info = new PackageRemovedInfo(this);
12555 info.removedPackage = packageName;
12556 info.installerPackageName = pkgSetting.installSource.installerPackageName;
12557 info.removedUsers = new int[] {userId};
12558 info.broadcastUsers = new int[] {userId};
12559 info.uid = UserHandle.getUid(userId, pkgSetting.appId);
12560 info.sendPackageRemovedBroadcasts(true /*killApp*/);
12563 private void sendDistractingPackagesChanged(String[] pkgList, int[] uidList, int userId,
12564 int distractionFlags) {
12565 final Bundle extras = new Bundle(3);
12566 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
12567 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
12568 extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags);
12569 sendPackageBroadcast(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null, extras,
12570 Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, new int[]{userId}, null);
12573 private void sendPackagesSuspendedForUser(String[] pkgList, int[] uidList, int userId,
12574 boolean suspended) {
12575 final Bundle extras = new Bundle(3);
12576 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
12577 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
12578 sendPackageBroadcast(
12579 suspended ? Intent.ACTION_PACKAGES_SUSPENDED
12580 : Intent.ACTION_PACKAGES_UNSUSPENDED,
12581 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
12582 new int[] {userId}, null);
12586 * Returns true if application is not found or there was an error. Otherwise it returns
12587 * the hidden state of the package for the given user.
12590 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
12591 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
12592 final int callingUid = Binder.getCallingUid();
12593 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
12594 true /* requireFullPermission */, false /* checkShell */,
12595 "getApplicationHidden for user " + userId);
12597 long callingId = Binder.clearCallingIdentity();
12600 synchronized (mLock) {
12601 ps = mSettings.mPackages.get(packageName);
12605 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
12608 return ps.getHidden(userId);
12611 Binder.restoreCallingIdentity(callingId);
12619 public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
12620 int installReason, List<String> whiteListedPermissions) {
12621 return installExistingPackageAsUser(packageName, userId, installFlags, installReason,
12622 whiteListedPermissions, null);
12625 int installExistingPackageAsUser(@Nullable String packageName, @UserIdInt int userId,
12626 @PackageManager.InstallFlags int installFlags,
12627 @PackageManager.InstallReason int installReason,
12628 @Nullable List<String> whiteListedPermissions, @Nullable IntentSender intentSender) {
12629 if (DEBUG_INSTALL) {
12630 Log.v(TAG, "installExistingPackageAsUser package=" + packageName + " userId=" + userId
12631 + " installFlags=" + installFlags + " installReason=" + installReason
12632 + " whiteListedPermissions=" + whiteListedPermissions);
12635 final int callingUid = Binder.getCallingUid();
12636 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES)
12637 != PackageManager.PERMISSION_GRANTED
12638 && mContext.checkCallingOrSelfPermission(
12639 android.Manifest.permission.INSTALL_EXISTING_PACKAGES)
12640 != PackageManager.PERMISSION_GRANTED) {
12641 throw new SecurityException("Neither user " + callingUid + " nor current process has "
12642 + android.Manifest.permission.INSTALL_PACKAGES + ".");
12644 PackageSetting pkgSetting;
12645 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
12646 true /* requireFullPermission */, true /* checkShell */,
12647 "installExistingPackage for user " + userId);
12648 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
12649 return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
12652 long callingId = Binder.clearCallingIdentity();
12654 boolean installed = false;
12655 final boolean instantApp =
12656 (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
12657 final boolean fullApp =
12658 (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
12661 synchronized (mLock) {
12662 pkgSetting = mSettings.mPackages.get(packageName);
12663 if (pkgSetting == null) {
12664 return PackageManager.INSTALL_FAILED_INVALID_URI;
12666 if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
12667 // only allow the existing package to be used if it's installed as a full
12668 // application for at least one user
12669 boolean installAllowed = false;
12670 for (int checkUserId : mUserManager.getUserIds()) {
12671 installAllowed = !pkgSetting.getInstantApp(checkUserId);
12672 if (installAllowed) {
12676 if (!installAllowed) {
12677 return PackageManager.INSTALL_FAILED_INVALID_URI;
12680 if (!pkgSetting.getInstalled(userId)) {
12681 pkgSetting.setInstalled(true, userId);
12682 pkgSetting.setHidden(false, userId);
12683 pkgSetting.setInstallReason(installReason, userId);
12684 mSettings.writePackageRestrictionsLPr(userId);
12685 mSettings.writeKernelMappingLPr(pkgSetting);
12687 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
12688 // upgrade app from instant to full; we don't allow app downgrade
12691 setInstantAppForUser(mInjector, pkgSetting, userId, instantApp, fullApp);
12695 if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS)
12696 != 0 && pkgSetting.pkg != null) {
12697 whiteListedPermissions = pkgSetting.pkg.getRequestedPermissions();
12699 mPermissionManager.setWhitelistedRestrictedPermissions(packageName,
12700 whiteListedPermissions, FLAG_PERMISSION_WHITELIST_INSTALLER, userId);
12702 if (pkgSetting.pkg != null) {
12703 synchronized (mInstallLock) {
12704 // We don't need to freeze for a brand new install
12705 prepareAppDataAfterInstallLIF(pkgSetting.pkg);
12708 sendPackageAddedForUser(packageName, pkgSetting, userId);
12709 synchronized (mLock) {
12710 updateSequenceNumberLP(pkgSetting, new int[]{ userId });
12712 // start async restore with no post-install since we finish install here
12713 PackageInstalledInfo res =
12714 createPackageInstalledInfo(PackageManager.INSTALL_SUCCEEDED);
12715 res.pkg = pkgSetting.pkg;
12716 res.newUsers = new int[]{ userId };
12717 PostInstallData postInstallData = intentSender == null ? null :
12718 new PostInstallData(null, res, () -> onRestoreComplete(res.returnCode,
12719 mContext, intentSender));
12720 restoreAndPostInstall(userId, res, postInstallData);
12723 Binder.restoreCallingIdentity(callingId);
12726 return PackageManager.INSTALL_SUCCEEDED;
12729 static void onRestoreComplete(int returnCode, Context context, IntentSender target) {
12730 Intent fillIn = new Intent();
12731 fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
12732 PackageManager.installStatusToPublicStatus(returnCode));
12734 target.sendIntent(context, 0, fillIn, null, null);
12735 } catch (SendIntentException ignored) {
12739 static void setInstantAppForUser(Injector injector, PackageSetting pkgSetting,
12740 int userId, boolean instantApp, boolean fullApp) {
12741 // no state specified; do nothing
12742 if (!instantApp && !fullApp) {
12745 if (userId != UserHandle.USER_ALL) {
12746 if (instantApp && !pkgSetting.getInstantApp(userId)) {
12747 pkgSetting.setInstantApp(true /*instantApp*/, userId);
12748 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
12749 pkgSetting.setInstantApp(false /*instantApp*/, userId);
12752 for (int currentUserId : injector.getUserManagerInternal().getUserIds()) {
12753 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
12754 pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
12755 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
12756 pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
12762 boolean isUserRestricted(int userId, String restrictionKey) {
12763 Bundle restrictions = mUserManager.getUserRestrictions(userId);
12764 if (restrictions.getBoolean(restrictionKey, false)) {
12765 Log.w(TAG, "User is restricted: " + restrictionKey);
12772 public String[] setDistractingPackageRestrictionsAsUser(String[] packageNames,
12773 int restrictionFlags, int userId) {
12774 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
12775 "setDistractingPackageRestrictionsAsUser");
12777 final int callingUid = Binder.getCallingUid();
12778 if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID
12779 && UserHandle.getUserId(callingUid) != userId) {
12780 throw new SecurityException("Calling uid " + callingUid + " cannot call for user "
12783 Objects.requireNonNull(packageNames, "packageNames cannot be null");
12784 if (restrictionFlags != 0 && !isSuspendAllowedForUser(userId)) {
12785 Slog.w(TAG, "Cannot restrict packages due to restrictions on user " + userId);
12786 return packageNames;
12789 final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
12790 final IntArray changedUids = new IntArray(packageNames.length);
12791 final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
12792 final boolean[] canRestrict = (restrictionFlags != 0) ? canSuspendPackageForUserInternal(
12793 packageNames, userId) : null;
12795 for (int i = 0; i < packageNames.length; i++) {
12796 final String packageName = packageNames[i];
12797 final PackageSetting pkgSetting;
12798 synchronized (mLock) {
12799 pkgSetting = mSettings.mPackages.get(packageName);
12800 if (pkgSetting == null
12801 || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
12802 Slog.w(TAG, "Could not find package setting for package: " + packageName
12803 + ". Skipping...");
12804 unactionedPackages.add(packageName);
12808 if (canRestrict != null && !canRestrict[i]) {
12809 unactionedPackages.add(packageName);
12812 synchronized (mLock) {
12813 final int oldDistractionFlags = pkgSetting.getDistractionFlags(userId);
12814 if (restrictionFlags != oldDistractionFlags) {
12815 pkgSetting.setDistractionFlags(restrictionFlags, userId);
12816 changedPackagesList.add(packageName);
12817 changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
12822 if (!changedPackagesList.isEmpty()) {
12823 final String[] changedPackages = changedPackagesList.toArray(
12824 new String[changedPackagesList.size()]);
12825 sendDistractingPackagesChanged(changedPackages, changedUids.toArray(), userId,
12827 synchronized (mLock) {
12828 scheduleWritePackageRestrictionsLocked(userId);
12831 return unactionedPackages.toArray(new String[0]);
12834 private void enforceCanSetPackagesSuspendedAsUser(String callingPackage, int callingUid,
12835 int userId, String callingMethod) {
12836 if (callingUid == Process.ROOT_UID || callingUid == Process.SYSTEM_UID) {
12840 final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
12841 if (ownerPackage != null) {
12842 final int ownerUid = getPackageUid(ownerPackage, 0, userId);
12843 if (ownerUid == callingUid) {
12848 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
12851 final int packageUid = getPackageUid(callingPackage, 0, userId);
12852 final boolean allowedPackageUid = packageUid == callingUid;
12853 // TODO(b/139383163): remove special casing for shell and enforce INTERACT_ACROSS_USERS_FULL
12854 final boolean allowedShell = callingUid == SHELL_UID
12855 && UserHandle.isSameApp(packageUid, callingUid);
12857 if (!allowedShell && !allowedPackageUid) {
12858 throw new SecurityException("Calling package " + callingPackage + " in user "
12859 + userId + " does not belong to calling uid " + callingUid);
12864 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
12865 PersistableBundle appExtras, PersistableBundle launcherExtras,
12866 SuspendDialogInfo dialogInfo, String callingPackage, int userId) {
12867 final int callingUid = Binder.getCallingUid();
12868 enforceCanSetPackagesSuspendedAsUser(callingPackage, callingUid, userId,
12869 "setPackagesSuspendedAsUser");
12871 if (ArrayUtils.isEmpty(packageNames)) {
12872 return packageNames;
12874 if (suspended && !isSuspendAllowedForUser(userId)) {
12875 Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId);
12876 return packageNames;
12879 final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
12880 final IntArray changedUids = new IntArray(packageNames.length);
12881 final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
12882 final boolean[] canSuspend = suspended ? canSuspendPackageForUserInternal(packageNames,
12885 for (int i = 0; i < packageNames.length; i++) {
12886 final String packageName = packageNames[i];
12887 if (callingPackage.equals(packageName)) {
12888 Slog.w(TAG, "Calling package: " + callingPackage + " trying to "
12889 + (suspended ? "" : "un") + "suspend itself. Ignoring");
12890 unactionedPackages.add(packageName);
12893 final PackageSetting pkgSetting;
12894 synchronized (mLock) {
12895 pkgSetting = mSettings.mPackages.get(packageName);
12896 if (pkgSetting == null
12897 || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
12898 Slog.w(TAG, "Could not find package setting for package: " + packageName
12899 + ". Skipping suspending/un-suspending.");
12900 unactionedPackages.add(packageName);
12904 if (canSuspend != null && !canSuspend[i]) {
12905 unactionedPackages.add(packageName);
12908 boolean packageUnsuspended;
12909 synchronized (mLock) {
12911 pkgSetting.addOrUpdateSuspension(callingPackage, dialogInfo, appExtras,
12912 launcherExtras, userId);
12914 pkgSetting.removeSuspension(callingPackage, userId);
12916 packageUnsuspended = !suspended && !pkgSetting.getSuspended(userId);
12918 if (suspended || packageUnsuspended) {
12919 changedPackagesList.add(packageName);
12920 changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
12924 if (!changedPackagesList.isEmpty()) {
12925 final String[] changedPackages = changedPackagesList.toArray(
12926 new String[changedPackagesList.size()]);
12927 sendPackagesSuspendedForUser(changedPackages, changedUids.toArray(), userId, suspended);
12928 sendMyPackageSuspendedOrUnsuspended(changedPackages, suspended, userId);
12929 synchronized (mLock) {
12930 scheduleWritePackageRestrictionsLocked(userId);
12933 return unactionedPackages.toArray(new String[unactionedPackages.size()]);
12937 public Bundle getSuspendedPackageAppExtras(String packageName, int userId) {
12938 final int callingUid = Binder.getCallingUid();
12939 if (getPackageUid(packageName, 0, userId) != callingUid) {
12940 throw new SecurityException("Calling package " + packageName
12941 + " does not belong to calling uid " + callingUid);
12943 return getSuspendedPackageAppExtrasInternal(packageName, userId);
12946 private Bundle getSuspendedPackageAppExtrasInternal(String packageName, int userId) {
12947 synchronized (mLock) {
12948 final PackageSetting ps = mSettings.mPackages.get(packageName);
12950 throw new IllegalArgumentException("Unknown target package: " + packageName);
12952 final PackageUserState pus = ps.readUserState(userId);
12953 final Bundle allExtras = new Bundle();
12954 if (pus.suspended) {
12955 for (int i = 0; i < pus.suspendParams.size(); i++) {
12956 final PackageUserState.SuspendParams params = pus.suspendParams.valueAt(i);
12957 if (params != null && params.appExtras != null) {
12958 allExtras.putAll(params.appExtras);
12962 return (allExtras.size() > 0) ? allExtras : null;
12966 private void sendMyPackageSuspendedOrUnsuspended(String[] affectedPackages, boolean suspended,
12968 final String action = suspended
12969 ? Intent.ACTION_MY_PACKAGE_SUSPENDED
12970 : Intent.ACTION_MY_PACKAGE_UNSUSPENDED;
12971 mHandler.post(() -> {
12973 final IActivityManager am = ActivityManager.getService();
12975 Slog.wtf(TAG, "IActivityManager null. Cannot send MY_PACKAGE_ "
12976 + (suspended ? "" : "UN") + "SUSPENDED broadcasts");
12979 final int[] targetUserIds = new int[] {userId};
12980 for (String packageName : affectedPackages) {
12981 final Bundle appExtras = suspended
12982 ? getSuspendedPackageAppExtrasInternal(packageName, userId)
12984 final Bundle intentExtras;
12985 if (appExtras != null) {
12986 intentExtras = new Bundle(1);
12987 intentExtras.putBundle(Intent.EXTRA_SUSPENDED_PACKAGE_EXTRAS, appExtras);
12989 intentExtras = null;
12991 doSendBroadcast(am, action, null, intentExtras,
12992 Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, packageName, null,
12993 targetUserIds, false);
12995 } catch (RemoteException ex) {
12996 // Shouldn't happen as AMS is in the same process.
13002 public boolean isPackageSuspendedForUser(String packageName, int userId) {
13003 final int callingUid = Binder.getCallingUid();
13004 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13005 true /* requireFullPermission */, false /* checkShell */,
13006 "isPackageSuspendedForUser for user " + userId);
13007 synchronized (mLock) {
13008 final PackageSetting ps = mSettings.mPackages.get(packageName);
13009 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
13010 throw new IllegalArgumentException("Unknown target package: " + packageName);
13012 return ps.getSuspended(userId);
13016 void unsuspendForSuspendingPackage(String suspendingPackage, int userId) {
13017 final String[] allPackages;
13018 synchronized (mLock) {
13019 allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
13021 removeSuspensionsBySuspendingPackage(allPackages, suspendingPackage::equals, userId);
13025 * Removes any suspensions on given packages that were added by packages that pass the given
13028 * <p> Caller must flush package restrictions if it cares about immediate data consistency.
13030 * @param packagesToChange The packages on which the suspension are to be removed.
13031 * @param suspendingPackagePredicate A predicate identifying the suspending packages whose
13032 * suspensions will be removed.
13033 * @param userId The user for which the changes are taking place.
13035 void removeSuspensionsBySuspendingPackage(String[] packagesToChange,
13036 Predicate<String> suspendingPackagePredicate, int userId) {
13037 final List<String> unsuspendedPackages = new ArrayList<>();
13038 final IntArray unsuspendedUids = new IntArray();
13039 synchronized (mLock) {
13040 for (String packageName : packagesToChange) {
13041 final PackageSetting ps = mSettings.mPackages.get(packageName);
13042 if (ps.getSuspended(userId)) {
13043 ps.removeSuspension(suspendingPackagePredicate, userId);
13044 if (!ps.getSuspended(userId)) {
13045 unsuspendedPackages.add(ps.name);
13046 unsuspendedUids.add(UserHandle.getUid(userId, ps.getAppId()));
13050 scheduleWritePackageRestrictionsLocked(userId);
13052 if (!unsuspendedPackages.isEmpty()) {
13053 final String[] packageArray = unsuspendedPackages.toArray(
13054 new String[unsuspendedPackages.size()]);
13055 sendMyPackageSuspendedOrUnsuspended(packageArray, false, userId);
13056 sendPackagesSuspendedForUser(packageArray, unsuspendedUids.toArray(), userId, false);
13060 void removeAllDistractingPackageRestrictions(int userId) {
13061 final String[] allPackages;
13062 synchronized (mLock) {
13063 allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
13065 PackageManagerService.this.removeDistractingPackageRestrictions(allPackages, userId);
13069 * Removes any {@link android.content.pm.PackageManager.DistractionRestriction restrictions}
13070 * set on given packages.
13072 * <p> Caller must flush package restrictions if it cares about immediate data consistency.
13074 * @param packagesToChange The packages on which restrictions are to be removed.
13075 * @param userId the user for which changes are taking place.
13077 void removeDistractingPackageRestrictions(String[] packagesToChange, int userId) {
13078 final List<String> changedPackages = new ArrayList<>();
13079 final IntArray changedUids = new IntArray();
13080 synchronized (mLock) {
13081 for (String packageName : packagesToChange) {
13082 final PackageSetting ps = mSettings.mPackages.get(packageName);
13083 if (ps.getDistractionFlags(userId) != 0) {
13084 ps.setDistractionFlags(0, userId);
13085 changedPackages.add(ps.name);
13086 changedUids.add(UserHandle.getUid(userId, ps.getAppId()));
13089 if (!changedPackages.isEmpty()) {
13090 final String[] packageArray = changedPackages.toArray(
13091 new String[changedPackages.size()]);
13092 sendDistractingPackagesChanged(packageArray, changedUids.toArray(), userId, 0);
13093 scheduleWritePackageRestrictionsLocked(userId);
13098 private boolean isCallerDeviceOrProfileOwner(int userId) {
13099 final int callingUid = Binder.getCallingUid();
13100 if (callingUid == Process.SYSTEM_UID) {
13103 final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
13104 if (ownerPackage != null) {
13105 return callingUid == getPackageUidInternal(ownerPackage, 0, userId, callingUid);
13110 private boolean isSuspendAllowedForUser(int userId) {
13111 return isCallerDeviceOrProfileOwner(userId)
13112 || (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL, userId)
13113 && !mUserManager.hasUserRestriction(UserManager.DISALLOW_UNINSTALL_APPS, userId));
13117 public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) {
13118 Objects.requireNonNull(packageNames, "packageNames cannot be null");
13119 mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
13120 "getUnsuspendablePackagesForUser");
13121 final int callingUid = Binder.getCallingUid();
13122 if (UserHandle.getUserId(callingUid) != userId) {
13123 throw new SecurityException("Calling uid " + callingUid
13124 + " cannot query getUnsuspendablePackagesForUser for user " + userId);
13126 if (!isSuspendAllowedForUser(userId)) {
13127 Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId);
13128 return packageNames;
13130 final ArraySet<String> unactionablePackages = new ArraySet<>();
13131 final boolean[] canSuspend = canSuspendPackageForUserInternal(packageNames, userId);
13132 for (int i = 0; i < packageNames.length; i++) {
13133 if (!canSuspend[i]) {
13134 unactionablePackages.add(packageNames[i]);
13137 synchronized (mLock) {
13138 final PackageSetting ps = mSettings.mPackages.get(packageNames[i]);
13139 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
13140 Slog.w(TAG, "Could not find package setting for package: " + packageNames[i]);
13141 unactionablePackages.add(packageNames[i]);
13145 return unactionablePackages.toArray(new String[unactionablePackages.size()]);
13149 * Returns an array of booleans, such that the ith boolean denotes whether the ith package can
13150 * be suspended or not.
13152 * @param packageNames The package names to check suspendability for.
13153 * @param userId The user to check in
13154 * @return An array containing results of the checks
13157 private boolean[] canSuspendPackageForUserInternal(@NonNull String[] packageNames, int userId) {
13158 final boolean[] canSuspend = new boolean[packageNames.length];
13159 final boolean isCallerOwner = isCallerDeviceOrProfileOwner(userId);
13160 final long callingId = Binder.clearCallingIdentity();
13162 final String activeLauncherPackageName = getActiveLauncherPackageName(userId);
13163 final String dialerPackageName = mPermissionManager.getDefaultDialer(userId);
13164 for (int i = 0; i < packageNames.length; i++) {
13165 canSuspend[i] = false;
13166 final String packageName = packageNames[i];
13168 if (isPackageDeviceAdmin(packageName, userId)) {
13169 Slog.w(TAG, "Cannot suspend package \"" + packageName
13170 + "\": has an active device admin");
13173 if (packageName.equals(activeLauncherPackageName)) {
13174 Slog.w(TAG, "Cannot suspend package \"" + packageName
13175 + "\": contains the active launcher");
13178 if (packageName.equals(mRequiredInstallerPackage)) {
13179 Slog.w(TAG, "Cannot suspend package \"" + packageName
13180 + "\": required for package installation");
13183 if (packageName.equals(mRequiredUninstallerPackage)) {
13184 Slog.w(TAG, "Cannot suspend package \"" + packageName
13185 + "\": required for package uninstallation");
13188 if (packageName.equals(mRequiredVerifierPackage)) {
13189 Slog.w(TAG, "Cannot suspend package \"" + packageName
13190 + "\": required for package verification");
13193 if (packageName.equals(dialerPackageName)) {
13194 Slog.w(TAG, "Cannot suspend package \"" + packageName
13195 + "\": is the default dialer");
13198 if (packageName.equals(mRequiredPermissionControllerPackage)) {
13199 Slog.w(TAG, "Cannot suspend package \"" + packageName
13200 + "\": required for permissions management");
13203 synchronized (mLock) {
13204 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13205 Slog.w(TAG, "Cannot suspend package \"" + packageName
13206 + "\": protected package");
13209 if (!isCallerOwner && mSettings.getBlockUninstallLPr(userId, packageName)) {
13210 Slog.w(TAG, "Cannot suspend package \"" + packageName
13211 + "\": blocked by admin");
13215 // Cannot suspend static shared libs as they are considered
13216 // a part of the using app (emulating static linking). Also
13217 // static libs are installed always on internal storage.
13218 AndroidPackage pkg = mPackages.get(packageName);
13219 if (pkg != null && pkg.isStaticSharedLibrary()) {
13220 Slog.w(TAG, "Cannot suspend package: " + packageName
13221 + " providing static shared library: "
13222 + pkg.getStaticSharedLibName());
13226 if (PLATFORM_PACKAGE_NAME.equals(packageName)) {
13227 Slog.w(TAG, "Cannot suspend the platform package: " + packageName);
13230 canSuspend[i] = true;
13233 Binder.restoreCallingIdentity(callingId);
13238 private String getActiveLauncherPackageName(int userId) {
13239 Intent intent = new Intent(Intent.ACTION_MAIN);
13240 intent.addCategory(Intent.CATEGORY_HOME);
13241 ResolveInfo resolveInfo = resolveIntent(
13243 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
13244 PackageManager.MATCH_DEFAULT_ONLY,
13247 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
13251 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
13252 mContext.enforceCallingOrSelfPermission(
13253 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13254 "Only package verification agents can verify applications");
13256 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13257 final PackageVerificationResponse response = new PackageVerificationResponse(
13258 verificationCode, Binder.getCallingUid());
13260 msg.obj = response;
13261 mHandler.sendMessage(msg);
13265 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
13266 long millisecondsToDelay) {
13267 mContext.enforceCallingOrSelfPermission(
13268 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13269 "Only package verification agents can extend verification timeouts");
13271 final PackageVerificationState state = mPendingVerification.get(id);
13272 final PackageVerificationResponse response = new PackageVerificationResponse(
13273 verificationCodeAtTimeout, Binder.getCallingUid());
13275 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
13276 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
13278 if (millisecondsToDelay < 0) {
13279 millisecondsToDelay = 0;
13281 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
13282 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
13283 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
13286 if ((state != null) && !state.timeoutExtended()) {
13287 state.extendTimeout();
13289 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13291 msg.obj = response;
13292 mHandler.sendMessageDelayed(msg, millisecondsToDelay);
13296 private void broadcastPackageVerified(int verificationId, Uri packageUri,
13297 int verificationCode, UserHandle user) {
13298 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
13299 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
13300 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
13301 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
13302 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
13304 mContext.sendBroadcastAsUser(intent, user,
13305 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
13308 private ComponentName matchComponentForVerifier(String packageName,
13309 List<ResolveInfo> receivers) {
13310 ActivityInfo targetReceiver = null;
13312 final int NR = receivers.size();
13313 for (int i = 0; i < NR; i++) {
13314 final ResolveInfo info = receivers.get(i);
13315 if (info.activityInfo == null) {
13319 if (packageName.equals(info.activityInfo.packageName)) {
13320 targetReceiver = info.activityInfo;
13325 if (targetReceiver == null) {
13329 return new ComponentName(targetReceiver.packageName, targetReceiver.name);
13332 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
13333 List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
13334 if (pkgInfo.verifiers.length == 0) {
13338 final int N = pkgInfo.verifiers.length;
13339 final List<ComponentName> sufficientVerifiers = new ArrayList<>(N + 1);
13340 for (int i = 0; i < N; i++) {
13341 final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
13343 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
13345 if (comp == null) {
13349 final int verifierUid = getUidForVerifier(verifierInfo);
13350 if (verifierUid == -1) {
13354 if (DEBUG_VERIFY) {
13355 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
13356 + " with the correct signature");
13358 sufficientVerifiers.add(comp);
13359 verificationState.addSufficientVerifier(verifierUid);
13362 return sufficientVerifiers;
13365 private int getUidForVerifier(VerifierInfo verifierInfo) {
13366 synchronized (mLock) {
13367 final AndroidPackage pkg = mPackages.get(verifierInfo.packageName);
13370 } else if (pkg.getSigningDetails().signatures.length != 1) {
13371 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13372 + " has more than one signature; ignoring");
13377 * If the public key of the package's signature does not match
13378 * our expected public key, then this is a different package and
13382 final byte[] expectedPublicKey;
13384 final Signature verifierSig = pkg.getSigningDetails().signatures[0];
13385 final PublicKey publicKey = verifierSig.getPublicKey();
13386 expectedPublicKey = publicKey.getEncoded();
13387 } catch (CertificateException e) {
13391 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
13393 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
13394 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13395 + " does not have the expected public key; ignoring");
13399 return pkg.getUid();
13403 private void setEnableRollbackCode(int token, int enableRollbackCode) {
13404 final Message msg = mHandler.obtainMessage(ENABLE_ROLLBACK_STATUS);
13406 msg.arg2 = enableRollbackCode;
13407 mHandler.sendMessage(msg);
13411 public void finishPackageInstall(int token, boolean didLaunch) {
13412 enforceSystemOrRoot("Only the system is allowed to finish installs");
13414 if (DEBUG_INSTALL) {
13415 Slog.v(TAG, "BM finishing package install for " + token);
13417 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13419 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
13420 mHandler.sendMessage(msg);
13424 * Get the verification agent timeout. Used for both the APK verifier and the
13425 * intent filter verifier.
13427 * @return verification timeout in milliseconds
13429 private long getVerificationTimeout() {
13430 long timeout = Global.getLong(mContext.getContentResolver(),
13431 Global.PACKAGE_VERIFIER_TIMEOUT, DEFAULT_VERIFICATION_TIMEOUT);
13432 // The setting can be used to increase the timeout but not decrease it, since that is
13433 // equivalent to disabling the verifier.
13434 return Math.max(timeout, DEFAULT_VERIFICATION_TIMEOUT);
13438 * Get the default verification agent response code.
13440 * @return default verification response code
13442 private int getDefaultVerificationResponse(UserHandle user) {
13443 if (mUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
13444 return PackageManager.VERIFICATION_REJECT;
13446 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13447 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
13448 DEFAULT_VERIFICATION_RESPONSE);
13452 * Get the default integrity verification response code.
13454 private int getDefaultIntegrityVerificationResponse() {
13455 // We are not exposing this as a user-configurable setting because we don't want to provide
13456 // an easy way to get around the integrity check.
13457 return PackageManager.VERIFICATION_REJECT;
13461 * Check whether or not package verification has been enabled.
13463 * @return true if verification should be performed
13465 private boolean isVerificationEnabled(
13466 PackageInfoLite pkgInfoLite, int userId, int installFlags, int installerUid) {
13467 if (!DEFAULT_VERIFY_ENABLE) {
13471 // Check if installing from ADB
13472 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
13473 if (isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS)) {
13476 // Check if the developer wants to skip verification for ADB installs
13477 if ((installFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0) {
13478 synchronized (mLock) {
13479 if (mSettings.mPackages.get(pkgInfoLite.packageName) == null) {
13480 // Always verify fresh install
13484 // Only skip when apk is debuggable
13485 return !pkgInfoLite.debuggable;
13487 return Global.getInt(mContext.getContentResolver(),
13488 Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0;
13491 if ((installFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0) {
13495 // only when not installed from ADB, skip verification for instant apps when
13496 // the installer and verifier are the same.
13497 if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13498 if (mInstantAppInstallerActivity != null
13499 && mInstantAppInstallerActivity.packageName.equals(
13500 mRequiredVerifierPackage)) {
13502 mInjector.getAppOpsManager()
13503 .checkPackage(installerUid, mRequiredVerifierPackage);
13504 if (DEBUG_VERIFY) {
13505 Slog.i(TAG, "disable verification for instant app");
13508 } catch (SecurityException ignore) { }
13515 * Check whether or not integrity verification has been enabled.
13517 private boolean isIntegrityVerificationEnabled() {
13518 // We are not exposing this as a user-configurable setting because we don't want to provide
13519 // an easy way to get around the integrity check.
13520 return DEFAULT_INTEGRITY_VERIFY_ENABLE;
13524 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
13525 throws RemoteException {
13526 mContext.enforceCallingOrSelfPermission(
13527 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
13528 "Only intentfilter verification agents can verify applications");
13530 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
13531 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
13532 Binder.getCallingUid(), verificationCode, failedDomains);
13534 msg.obj = response;
13535 mHandler.sendMessage(msg);
13539 public int getIntentVerificationStatus(String packageName, int userId) {
13540 final int callingUid = Binder.getCallingUid();
13541 if (UserHandle.getUserId(callingUid) != userId) {
13542 mContext.enforceCallingOrSelfPermission(
13543 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13544 "getIntentVerificationStatus" + userId);
13546 if (getInstantAppPackageName(callingUid) != null) {
13547 return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
13549 synchronized (mLock) {
13550 final PackageSetting ps = mSettings.mPackages.get(packageName);
13552 || shouldFilterApplicationLocked(
13553 ps, callingUid, UserHandle.getUserId(callingUid))) {
13554 return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
13556 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
13561 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
13562 mContext.enforceCallingOrSelfPermission(
13563 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
13565 boolean result = false;
13566 synchronized (mLock) {
13567 final PackageSetting ps = mSettings.mPackages.get(packageName);
13568 if (shouldFilterApplicationLocked(
13569 ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
13572 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
13575 scheduleWritePackageRestrictionsLocked(userId);
13581 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
13582 String packageName) {
13583 final int callingUid = Binder.getCallingUid();
13584 if (getInstantAppPackageName(callingUid) != null) {
13585 return ParceledListSlice.emptyList();
13587 synchronized (mLock) {
13588 final PackageSetting ps = mSettings.mPackages.get(packageName);
13589 if (shouldFilterApplicationLocked(ps, callingUid, UserHandle.getUserId(callingUid))) {
13590 return ParceledListSlice.emptyList();
13592 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
13597 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
13598 if (TextUtils.isEmpty(packageName)) {
13599 return ParceledListSlice.emptyList();
13601 final int callingUid = Binder.getCallingUid();
13602 final int callingUserId = UserHandle.getUserId(callingUid);
13603 synchronized (mLock) {
13604 AndroidPackage pkg = mPackages.get(packageName);
13605 if (pkg == null || ArrayUtils.isEmpty(pkg.getActivities())) {
13606 return ParceledListSlice.emptyList();
13608 final PackageSetting ps = getPackageSetting(pkg.getPackageName());
13610 return ParceledListSlice.emptyList();
13612 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
13613 return ParceledListSlice.emptyList();
13615 final int count = ArrayUtils.size(pkg.getActivities());
13616 ArrayList<IntentFilter> result = new ArrayList<>();
13617 for (int n=0; n<count; n++) {
13618 ParsedActivity activity = pkg.getActivities().get(n);
13619 if (activity.getIntents() != null && activity.getIntents().size() > 0) {
13620 result.addAll(activity.getIntents());
13623 return new ParceledListSlice<IntentFilter>(result) {
13625 protected void writeElement(IntentFilter parcelable, Parcel dest, int callFlags) {
13626 // IntentFilter has final Parcelable methods, so redirect to the subclass
13627 ((ParsedIntentInfo) parcelable).writeIntentInfoToParcel(dest,
13635 * Get the "allow unknown sources" setting.
13637 * @return the current "allow unknown sources" setting
13639 private int getUnknownSourcesSettings() {
13640 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
13641 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
13646 public void setInstallerPackageName(String targetPackage, String installerPackageName) {
13647 final int callingUid = Binder.getCallingUid();
13648 if (getInstantAppPackageName(callingUid) != null) {
13652 synchronized (mLock) {
13653 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
13654 if (targetPackageSetting == null
13655 || shouldFilterApplicationLocked(
13656 targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
13657 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
13660 PackageSetting installerPackageSetting;
13661 if (installerPackageName != null) {
13662 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
13663 if (installerPackageSetting == null) {
13664 throw new IllegalArgumentException("Unknown installer package: "
13665 + installerPackageName);
13668 installerPackageSetting = null;
13671 Signature[] callerSignature;
13672 final int appId = UserHandle.getAppId(callingUid);
13673 final Object obj = mSettings.getSettingLPr(appId);
13675 if (obj instanceof SharedUserSetting) {
13677 ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
13678 } else if (obj instanceof PackageSetting) {
13679 callerSignature = ((PackageSetting)obj).signatures.mSigningDetails.signatures;
13681 throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
13684 throw new SecurityException("Unknown calling UID: " + callingUid);
13687 // Verify: can't set installerPackageName to a package that is
13688 // not signed with the same cert as the caller.
13689 if (installerPackageSetting != null) {
13690 if (compareSignatures(callerSignature,
13691 installerPackageSetting.signatures.mSigningDetails.signatures)
13692 != PackageManager.SIGNATURE_MATCH) {
13693 throw new SecurityException(
13694 "Caller does not have same cert as new installer package "
13695 + installerPackageName);
13699 // Verify: if target already has an installer package, it must
13700 // be signed with the same cert as the caller.
13701 String targetInstallerPackageName =
13702 targetPackageSetting.installSource.installerPackageName;
13703 if (targetInstallerPackageName != null) {
13704 PackageSetting setting = mSettings.mPackages.get(
13705 targetInstallerPackageName);
13706 // If the currently set package isn't valid, then it's always
13707 // okay to change it.
13708 if (setting != null) {
13709 if (compareSignatures(callerSignature,
13710 setting.signatures.mSigningDetails.signatures)
13711 != PackageManager.SIGNATURE_MATCH) {
13712 throw new SecurityException(
13713 "Caller does not have same cert as old installer package "
13714 + targetInstallerPackageName);
13720 targetPackageSetting.setInstallerPackageName(installerPackageName);
13721 mSettings.addInstallerPackageNames(targetPackageSetting.installSource);
13722 mAppsFilter.addPackage(targetPackageSetting, mSettings.mPackages);
13723 scheduleWriteSettingsLocked();
13728 public void setApplicationCategoryHint(String packageName, int categoryHint,
13729 String callerPackageName) {
13730 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
13731 throw new SecurityException("Instant applications don't have access to this method");
13733 mInjector.getAppOpsManager().checkPackage(Binder.getCallingUid(),
13734 callerPackageName);
13735 synchronized (mLock) {
13736 PackageSetting ps = mSettings.mPackages.get(packageName);
13738 throw new IllegalArgumentException("Unknown target package " + packageName);
13740 if (shouldFilterApplicationLocked(
13741 ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
13742 throw new IllegalArgumentException("Unknown target package " + packageName);
13744 if (!Objects.equals(callerPackageName, ps.installSource.installerPackageName)) {
13745 throw new IllegalArgumentException("Calling package " + callerPackageName
13746 + " is not installer for " + packageName);
13749 if (ps.categoryHint != categoryHint) {
13750 ps.categoryHint = categoryHint;
13751 scheduleWriteSettingsLocked();
13756 private void processPendingInstall(final InstallArgs args, final int currentStatus) {
13757 if (args.mMultiPackageInstallParams != null) {
13758 args.mMultiPackageInstallParams.tryProcessInstallRequest(args, currentStatus);
13760 PackageInstalledInfo res = createPackageInstalledInfo(currentStatus);
13761 processInstallRequestsAsync(
13762 res.returnCode == PackageManager.INSTALL_SUCCEEDED,
13763 Collections.singletonList(new InstallRequest(args, res)));
13767 // Queue up an async operation since the package installation may take a little while.
13768 private void processInstallRequestsAsync(boolean success,
13769 List<InstallRequest> installRequests) {
13770 mHandler.post(() -> {
13772 for (InstallRequest request : installRequests) {
13773 request.args.doPreInstall(request.installResult.returnCode);
13775 synchronized (mInstallLock) {
13776 installPackagesTracedLI(installRequests);
13778 for (InstallRequest request : installRequests) {
13779 request.args.doPostInstall(
13780 request.installResult.returnCode, request.installResult.uid);
13783 for (InstallRequest request : installRequests) {
13784 restoreAndPostInstall(request.args.user.getIdentifier(), request.installResult,
13785 new PostInstallData(request.args, request.installResult, null));
13790 private PackageInstalledInfo createPackageInstalledInfo(
13791 int currentStatus) {
13792 PackageInstalledInfo res = new PackageInstalledInfo();
13793 res.setReturnCode(currentStatus);
13796 res.removedInfo = null;
13800 /** @param data Post-install is performed only if this is non-null. */
13801 private void restoreAndPostInstall(
13802 int userId, PackageInstalledInfo res, @Nullable PostInstallData data) {
13803 if (DEBUG_INSTALL) {
13804 Log.v(TAG, "restoreAndPostInstall userId=" + userId + " package=" + res.pkg);
13807 // A restore should be performed at this point if (a) the install
13808 // succeeded, (b) the operation is not an update, and (c) the new
13809 // package has not opted out of backup participation.
13810 final boolean update = res.removedInfo != null
13811 && res.removedInfo.removedPackage != null;
13812 boolean allowBackup = res.pkg != null && res.pkg.isAllowBackup();
13813 boolean doRestore = !update && allowBackup;
13815 // Set up the post-install work request bookkeeping. This will be used
13816 // and cleaned up by the post-install event handling regardless of whether
13817 // there's a restore pass performed. Token values are >= 1.
13819 if (mNextInstallToken < 0) mNextInstallToken = 1;
13820 token = mNextInstallToken++;
13821 if (data != null) {
13822 mRunningInstalls.put(token, data);
13823 } else if (DEBUG_INSTALL) {
13824 Log.v(TAG, "No post-install required for " + token);
13827 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
13829 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
13830 // Pass responsibility to the Backup Manager. It will perform a
13831 // restore if appropriate, then pass responsibility back to the
13832 // Package Manager to run the post-install observer callbacks
13834 if (res.freezer != null) {
13835 res.freezer.close();
13837 doRestore = performBackupManagerRestore(userId, token, res);
13840 // If this is an update to a package that might be potentially downgraded, then we
13841 // need to check with the rollback manager whether there's any userdata that might
13842 // need to be snapshotted or restored for the package.
13844 // TODO(narayan): Get this working for cases where userId == UserHandle.USER_ALL.
13845 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && !doRestore && update) {
13846 doRestore = performRollbackManagerRestore(userId, token, res, data);
13850 // No restore possible, or the Backup Manager was mysteriously not
13851 // available -- just fire the post-install work request directly.
13852 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
13854 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
13856 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
13857 mHandler.sendMessage(msg);
13862 * Perform Backup Manager restore for a given {@link PackageInstalledInfo}.
13863 * Returns whether the restore successfully completed.
13865 private boolean performBackupManagerRestore(int userId, int token, PackageInstalledInfo res) {
13866 IBackupManager bm = IBackupManager.Stub.asInterface(
13867 ServiceManager.getService(Context.BACKUP_SERVICE));
13869 // For backwards compatibility as USER_ALL previously routed directly to USER_SYSTEM
13870 // in the BackupManager. USER_ALL is used in compatibility tests.
13871 if (userId == UserHandle.USER_ALL) {
13872 userId = UserHandle.USER_SYSTEM;
13874 if (DEBUG_INSTALL) {
13875 Log.v(TAG, "token " + token + " to BM for possible restore for user " + userId);
13877 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13879 if (bm.isUserReadyForBackup(userId)) {
13880 bm.restoreAtInstallForUser(
13881 userId, res.pkg.getPackageName(), token);
13883 Slog.w(TAG, "User " + userId + " is not ready. Restore at install "
13884 + "didn't take place.");
13887 } catch (RemoteException e) {
13888 // can't happen; the backup manager is local
13889 } catch (Exception e) {
13890 Slog.e(TAG, "Exception trying to enqueue restore", e);
13894 Slog.e(TAG, "Backup Manager not found!");
13901 * Perform Rollback Manager restore for a given {@link PackageInstalledInfo}.
13902 * Returns whether the restore successfully completed.
13904 private boolean performRollbackManagerRestore(int userId, int token, PackageInstalledInfo res,
13905 PostInstallData data) {
13906 IRollbackManager rm = IRollbackManager.Stub.asInterface(
13907 ServiceManager.getService(Context.ROLLBACK_SERVICE));
13909 final String packageName = res.pkg.getPackageName();
13910 final int[] allUsers = mUserManager.getUserIds();
13911 final int[] installedUsers;
13913 final PackageSetting ps;
13915 long ceDataInode = -1;
13916 synchronized (mSettings) {
13917 ps = mSettings.getPackageLPr(packageName);
13920 ceDataInode = ps.getCeDataInode(userId);
13923 // NOTE: We ignore the user specified in the InstallParam because we know this is
13924 // an update, and hence need to restore data for all installed users.
13925 installedUsers = ps.queryInstalledUsers(allUsers, true);
13928 boolean doSnapshotOrRestore = data != null && data.args != null
13929 && ((data.args.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0
13930 || (data.args.installFlags & PackageManager.INSTALL_REQUEST_DOWNGRADE) != 0);
13932 if (ps != null && doSnapshotOrRestore) {
13933 final String seInfo = AndroidPackageUtils.getSeInfo(res.pkg, ps);
13935 rm.snapshotAndRestoreUserData(packageName, installedUsers, appId, ceDataInode,
13937 } catch (RemoteException re) {
13938 Log.e(TAG, "Error snapshotting/restoring user data: " + re);
13947 * Callback from PackageSettings whenever an app is first transitioned out of the
13948 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if
13949 * the app was "launched" for a restoreAtInstall operation. Therefore we check
13950 * here whether the app is the target of an ongoing install, and only send the
13951 * broadcast immediately if it is not in that state. If it *is* undergoing a restore,
13952 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
13955 void notifyFirstLaunch(final String packageName, final String installerPackage,
13956 final int userId) {
13957 // Serialize this with the rest of the install-process message chain. In the
13958 // restore-at-install case, this Runnable will necessarily run before the
13959 // POST_INSTALL message is processed, so the contents of mRunningInstalls
13960 // are coherent. In the non-restore case, the app has already completed install
13961 // and been launched through some other means, so it is not in a problematic
13962 // state for observers to see the FIRST_LAUNCH signal.
13963 mHandler.post(() -> {
13964 for (int i = 0; i < mRunningInstalls.size(); i++) {
13965 final PostInstallData data = mRunningInstalls.valueAt(i);
13966 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
13969 if (packageName.equals(data.res.pkg.getPackageName())) {
13970 // right package; but is it for the right user?
13971 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
13972 if (userId == data.res.newUsers[uIndex]) {
13973 if (DEBUG_BACKUP) {
13974 Slog.i(TAG, "Package " + packageName
13975 + " being restored so deferring FIRST_LAUNCH");
13982 // didn't find it, so not being restored
13983 if (DEBUG_BACKUP) {
13984 Slog.i(TAG, "Package " + packageName + " sending normal FIRST_LAUNCH");
13986 final boolean isInstantApp = isInstantApp(packageName, userId);
13987 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
13988 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
13989 sendFirstLaunchBroadcast(packageName, installerPackage, userIds, instantUserIds);
13993 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg,
13994 int[] userIds, int[] instantUserIds) {
13995 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
13996 installerPkg, null, userIds, instantUserIds);
13999 private abstract class HandlerParams {
14000 /** User handle for the user requesting the information or installation. */
14001 private final UserHandle mUser;
14002 String traceMethod;
14005 HandlerParams(UserHandle user) {
14009 UserHandle getUser() {
14014 * Gets the user handle for the user that the rollback agent should
14015 * use to look up information about this installation when enabling
14018 UserHandle getRollbackUser() {
14019 // The session for packages installed for "all" users is
14020 // associated with the "system" user.
14021 if (mUser == UserHandle.ALL) {
14022 return UserHandle.SYSTEM;
14027 HandlerParams setTraceMethod(String traceMethod) {
14028 this.traceMethod = traceMethod;
14032 HandlerParams setTraceCookie(int traceCookie) {
14033 this.traceCookie = traceCookie;
14037 final void startCopy() {
14038 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14040 handleReturnCode();
14043 abstract void handleStartCopy();
14044 abstract void handleReturnCode();
14047 static class OriginInfo {
14049 * Location where install is coming from, before it has been
14050 * copied/renamed into place. This could be a single monolithic APK
14051 * file, or a cluster directory. This location may be untrusted.
14056 * Flag indicating that {@link #file} has already been staged, meaning downstream users
14057 * don't need to defensively copy the contents.
14059 final boolean staged;
14062 * Flag indicating that {@link #file} is an already installed app that is being moved.
14064 final boolean existing;
14066 final String resolvedPath;
14067 final File resolvedFile;
14069 static OriginInfo fromNothing() {
14070 return new OriginInfo(null, false, false);
14073 static OriginInfo fromUntrustedFile(File file) {
14074 return new OriginInfo(file, false, false);
14077 static OriginInfo fromExistingFile(File file) {
14078 return new OriginInfo(file, false, true);
14081 static OriginInfo fromStagedFile(File file) {
14082 return new OriginInfo(file, true, false);
14085 private OriginInfo(File file, boolean staged, boolean existing) {
14087 this.staged = staged;
14088 this.existing = existing;
14090 if (file != null) {
14091 resolvedPath = file.getAbsolutePath();
14092 resolvedFile = file;
14094 resolvedPath = null;
14095 resolvedFile = null;
14100 static class MoveInfo {
14102 final String fromUuid;
14103 final String toUuid;
14104 final String packageName;
14106 final String seinfo;
14107 final int targetSdkVersion;
14108 final String fromCodePath;
14110 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14111 int appId, String seinfo, int targetSdkVersion,
14112 String fromCodePath) {
14113 this.moveId = moveId;
14114 this.fromUuid = fromUuid;
14115 this.toUuid = toUuid;
14116 this.packageName = packageName;
14117 this.appId = appId;
14118 this.seinfo = seinfo;
14119 this.targetSdkVersion = targetSdkVersion;
14120 this.fromCodePath = fromCodePath;
14124 static class VerificationInfo {
14125 /** A constant used to indicate that a uid value is not present. */
14126 public static final int NO_UID = -1;
14128 /** URI referencing where the package was downloaded from. */
14129 final Uri originatingUri;
14131 /** HTTP referrer URI associated with the originatingURI. */
14132 final Uri referrer;
14134 /** UID of the application that the install request originated from. */
14135 final int originatingUid;
14137 /** UID of application requesting the install */
14138 final int installerUid;
14140 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14141 this.originatingUri = originatingUri;
14142 this.referrer = referrer;
14143 this.originatingUid = originatingUid;
14144 this.installerUid = installerUid;
14149 * Container for a multi-package install which refers to all install sessions and args being
14150 * committed together.
14152 class MultiPackageInstallParams extends HandlerParams {
14154 private int mRet = INSTALL_SUCCEEDED;
14156 private final ArrayList<InstallParams> mChildParams;
14158 private final Map<InstallArgs, Integer> mCurrentState;
14160 MultiPackageInstallParams(
14161 @NonNull UserHandle user,
14162 @NonNull List<ActiveInstallSession> activeInstallSessions)
14163 throws PackageManagerException {
14165 if (activeInstallSessions.size() == 0) {
14166 throw new PackageManagerException("No child sessions found!");
14168 mChildParams = new ArrayList<>(activeInstallSessions.size());
14169 for (int i = 0; i < activeInstallSessions.size(); i++) {
14170 final InstallParams childParams = new InstallParams(activeInstallSessions.get(i));
14171 childParams.mParentInstallParams = this;
14172 this.mChildParams.add(childParams);
14174 this.mCurrentState = new ArrayMap<>(mChildParams.size());
14178 void handleStartCopy() {
14179 for (InstallParams params : mChildParams) {
14180 params.handleStartCopy();
14181 if (params.mRet != INSTALL_SUCCEEDED) {
14182 mRet = params.mRet;
14188 void handleReturnCode() {
14189 for (InstallParams params : mChildParams) {
14190 params.handleReturnCode();
14191 if (params.mRet != INSTALL_SUCCEEDED) {
14192 mRet = params.mRet;
14197 void tryProcessInstallRequest(InstallArgs args, int currentStatus) {
14198 mCurrentState.put(args, currentStatus);
14199 if (mCurrentState.size() != mChildParams.size()) {
14202 int completeStatus = PackageManager.INSTALL_SUCCEEDED;
14203 for (Integer status : mCurrentState.values()) {
14204 if (status == PackageManager.INSTALL_UNKNOWN) {
14206 } else if (status != PackageManager.INSTALL_SUCCEEDED) {
14207 completeStatus = status;
14211 final List<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size());
14212 for (Map.Entry<InstallArgs, Integer> entry : mCurrentState.entrySet()) {
14213 installRequests.add(new InstallRequest(entry.getKey(),
14214 createPackageInstalledInfo(completeStatus)));
14216 processInstallRequestsAsync(
14217 completeStatus == PackageManager.INSTALL_SUCCEEDED,
14222 class InstallParams extends HandlerParams {
14223 // TODO: see if we can collapse this into ActiveInstallSession
14225 final OriginInfo origin;
14226 final MoveInfo move;
14227 final IPackageInstallObserver2 observer;
14229 @NonNull final InstallSource installSource;
14230 final String volumeUuid;
14231 private boolean mVerificationCompleted;
14232 private boolean mIntegrityVerificationCompleted;
14233 private boolean mEnableRollbackCompleted;
14234 private InstallArgs mArgs;
14236 final String packageAbiOverride;
14237 final String[] grantedRuntimePermissions;
14238 final List<String> whitelistedRestrictedPermissions;
14239 final VerificationInfo verificationInfo;
14240 final PackageParser.SigningDetails signingDetails;
14241 final int installReason;
14243 MultiPackageInstallParams mParentInstallParams;
14244 final long requiredInstalledVersionCode;
14245 final boolean forceQueryableOverride;
14246 final int mDataLoaderType;
14247 final int mSessionId;
14249 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14250 int installFlags, InstallSource installSource, String volumeUuid,
14251 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14252 String[] grantedPermissions, List<String> whitelistedRestrictedPermissions,
14253 SigningDetails signingDetails, int installReason,
14254 long requiredInstalledVersionCode, int dataLoaderType) {
14256 this.origin = origin;
14258 this.observer = observer;
14259 this.installFlags = installFlags;
14260 this.installSource = Preconditions.checkNotNull(installSource);
14261 this.volumeUuid = volumeUuid;
14262 this.verificationInfo = verificationInfo;
14263 this.packageAbiOverride = packageAbiOverride;
14264 this.grantedRuntimePermissions = grantedPermissions;
14265 this.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
14266 this.signingDetails = signingDetails;
14267 this.installReason = installReason;
14268 this.requiredInstalledVersionCode = requiredInstalledVersionCode;
14269 this.forceQueryableOverride = false;
14270 this.mDataLoaderType = dataLoaderType;
14271 this.mSessionId = -1;
14274 InstallParams(ActiveInstallSession activeInstallSession) {
14275 super(activeInstallSession.getUser());
14276 final PackageInstaller.SessionParams sessionParams =
14277 activeInstallSession.getSessionParams();
14278 if (DEBUG_INSTANT) {
14279 if ((sessionParams.installFlags
14280 & PackageManager.INSTALL_INSTANT_APP) != 0) {
14281 Slog.d(TAG, "Ephemeral install of " + activeInstallSession.getPackageName());
14284 verificationInfo = new VerificationInfo(
14285 sessionParams.originatingUri,
14286 sessionParams.referrerUri,
14287 sessionParams.originatingUid,
14288 activeInstallSession.getInstallerUid());
14289 origin = OriginInfo.fromStagedFile(activeInstallSession.getStagedDir());
14291 installReason = fixUpInstallReason(
14292 activeInstallSession.getInstallSource().installerPackageName,
14293 activeInstallSession.getInstallerUid(),
14294 sessionParams.installReason);
14295 observer = activeInstallSession.getObserver();
14296 installFlags = sessionParams.installFlags;
14297 installSource = activeInstallSession.getInstallSource();
14298 volumeUuid = sessionParams.volumeUuid;
14299 packageAbiOverride = sessionParams.abiOverride;
14300 grantedRuntimePermissions = sessionParams.grantedRuntimePermissions;
14301 whitelistedRestrictedPermissions = sessionParams.whitelistedRestrictedPermissions;
14302 signingDetails = activeInstallSession.getSigningDetails();
14303 requiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode;
14304 forceQueryableOverride = sessionParams.forceQueryableOverride;
14305 mDataLoaderType = (sessionParams.dataLoaderParams != null)
14306 ? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE;
14307 mSessionId = activeInstallSession.getSessionId();
14311 public String toString() {
14312 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14313 + " file=" + origin.file + "}";
14316 private int installLocationPolicy(PackageInfoLite pkgLite) {
14317 String packageName = pkgLite.packageName;
14318 int installLocation = pkgLite.installLocation;
14320 synchronized (mLock) {
14321 // Currently installed package which the new package is attempting to replace or
14322 // null if no such package is installed.
14323 AndroidPackage installedPkg = mPackages.get(packageName);
14324 // Package which currently owns the data which the new package will own if installed.
14325 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14326 // will be null whereas dataOwnerPkg will contain information about the package
14327 // which was uninstalled while keeping its data.
14328 AndroidPackage dataOwnerPkg = installedPkg;
14329 if (dataOwnerPkg == null) {
14330 PackageSetting ps = mSettings.mPackages.get(packageName);
14332 dataOwnerPkg = ps.pkg;
14336 if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST) {
14337 if (dataOwnerPkg == null) {
14338 Slog.w(TAG, "Required installed version code was "
14339 + requiredInstalledVersionCode
14340 + " but package is not installed");
14341 return PackageHelper.RECOMMEND_FAILED_WRONG_INSTALLED_VERSION;
14344 if (dataOwnerPkg.getLongVersionCode() != requiredInstalledVersionCode) {
14345 Slog.w(TAG, "Required installed version code was "
14346 + requiredInstalledVersionCode
14347 + " but actual installed version is "
14348 + dataOwnerPkg.getLongVersionCode());
14349 return PackageHelper.RECOMMEND_FAILED_WRONG_INSTALLED_VERSION;
14353 if (dataOwnerPkg != null) {
14354 if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags,
14355 dataOwnerPkg.isDebuggable())) {
14357 checkDowngrade(dataOwnerPkg, pkgLite);
14358 } catch (PackageManagerException e) {
14359 Slog.w(TAG, "Downgrade detected: " + e.getMessage());
14360 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
14365 if (installedPkg != null) {
14366 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
14367 // Check for updated system application.
14368 if (installedPkg.isSystem()) {
14369 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14371 // If current upgrade specifies particular preference
14372 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
14373 // Application explicitly specified internal.
14374 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14375 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
14376 // App explictly prefers external. Let policy decide
14378 // Prefer previous location
14379 if (installedPkg.isExternalStorage()) {
14380 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14382 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14386 // Invalid install. Return error code
14387 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
14391 return pkgLite.recommendedInstallLocation;
14395 * Invoke remote method to get package information and install
14396 * location values. Override install location based on default
14397 * policy if needed and then create install arguments based
14398 * on the install location.
14400 public void handleStartCopy() {
14401 int ret = PackageManager.INSTALL_SUCCEEDED;
14403 // If we're already staged, we've firmly committed to an install location
14404 if (origin.staged) {
14405 if (origin.file != null) {
14406 installFlags |= PackageManager.INSTALL_INTERNAL;
14408 throw new IllegalStateException("Invalid stage location");
14412 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
14413 final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14414 PackageInfoLite pkgLite = null;
14417 pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
14418 origin.resolvedPath, installFlags, packageAbiOverride);
14420 if (DEBUG_INSTANT && ephemeral) {
14421 Slog.v(TAG, "pkgLite for install: " + pkgLite);
14425 * If we have too little free space, try to free cache
14426 * before giving up.
14428 if (!origin.staged && pkgLite.recommendedInstallLocation
14429 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14430 // TODO: focus freeing disk space on the target device
14431 final StorageManager storage = StorageManager.from(mContext);
14432 final long lowThreshold = storage.getStorageLowBytes(
14433 Environment.getDataDirectory());
14435 final long sizeBytes = PackageManagerServiceUtils.calculateInstalledSize(
14436 origin.resolvedPath, packageAbiOverride);
14437 if (sizeBytes >= 0) {
14439 mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
14440 pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
14441 origin.resolvedPath, installFlags, packageAbiOverride);
14442 } catch (InstallerException e) {
14443 Slog.w(TAG, "Failed to free cache", e);
14448 * The cache free must have deleted the file we downloaded to install.
14450 * TODO: fix the "freeCache" call to not delete the file we care about.
14452 if (pkgLite.recommendedInstallLocation
14453 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14454 pkgLite.recommendedInstallLocation
14455 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
14460 if (ret == PackageManager.INSTALL_SUCCEEDED) {
14461 int loc = pkgLite.recommendedInstallLocation;
14462 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
14463 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14464 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
14465 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
14466 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14467 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
14468 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
14469 ret = PackageManager.INSTALL_FAILED_INVALID_APK;
14470 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14471 ret = PackageManager.INSTALL_FAILED_INVALID_URI;
14472 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
14473 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
14475 // Override with defaults if needed.
14476 loc = installLocationPolicy(pkgLite);
14477 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
14478 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
14479 } else if (loc == PackageHelper.RECOMMEND_FAILED_WRONG_INSTALLED_VERSION) {
14480 ret = PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION;
14481 } else if (!onInt) {
14482 // Override install location with flags
14483 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
14484 // Set the flag to install on external media.
14485 installFlags &= ~PackageManager.INSTALL_INTERNAL;
14486 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
14487 if (DEBUG_INSTANT) {
14488 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
14490 installFlags |= PackageManager.INSTALL_INSTANT_APP;
14491 installFlags &= ~PackageManager.INSTALL_INTERNAL;
14493 // Make sure the flag for installing on external
14495 installFlags |= PackageManager.INSTALL_INTERNAL;
14501 final InstallArgs args = createInstallArgs(this);
14502 mVerificationCompleted = true;
14503 mIntegrityVerificationCompleted = true;
14504 mEnableRollbackCompleted = true;
14507 if (ret == PackageManager.INSTALL_SUCCEEDED) {
14508 final int verificationId = mPendingVerificationToken++;
14510 // Perform package verification (unless we are simply moving the package).
14511 if (!origin.existing) {
14512 PackageVerificationState verificationState =
14513 new PackageVerificationState(this);
14514 mPendingVerification.append(verificationId, verificationState);
14516 sendIntegrityVerificationRequest(verificationId, pkgLite, verificationState);
14517 ret = sendPackageVerificationRequest(
14518 verificationId, pkgLite, verificationState);
14520 // If both verifications are skipped, we should remove the state.
14521 if (verificationState.areAllVerificationsComplete()) {
14522 mPendingVerification.remove(verificationId);
14527 if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
14528 // TODO(ruhler) b/112431924: Don't do this in case of 'move'?
14529 final int enableRollbackToken = mPendingEnableRollbackToken++;
14530 Trace.asyncTraceBegin(
14531 TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
14532 mPendingEnableRollback.append(enableRollbackToken, this);
14534 Intent enableRollbackIntent = new Intent(Intent.ACTION_PACKAGE_ENABLE_ROLLBACK);
14535 enableRollbackIntent.putExtra(
14536 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN,
14537 enableRollbackToken);
14538 enableRollbackIntent.putExtra(
14539 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_SESSION_ID,
14541 enableRollbackIntent.setType(PACKAGE_MIME_TYPE);
14542 enableRollbackIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14544 // Allow the broadcast to be sent before boot complete.
14545 // This is needed when committing the apk part of a staged
14546 // session in early boot. The rollback manager registers
14547 // its receiver early enough during the boot process that
14548 // it will not miss the broadcast.
14549 enableRollbackIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
14551 mContext.sendOrderedBroadcastAsUser(enableRollbackIntent, UserHandle.SYSTEM,
14552 android.Manifest.permission.PACKAGE_ROLLBACK_AGENT,
14553 new BroadcastReceiver() {
14555 public void onReceive(Context context, Intent intent) {
14556 // the duration to wait for rollback to be enabled, in millis
14557 long rollbackTimeout = DeviceConfig.getLong(
14558 DeviceConfig.NAMESPACE_ROLLBACK,
14559 PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS,
14560 DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS);
14561 if (rollbackTimeout < 0) {
14562 rollbackTimeout = DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS;
14564 final Message msg = mHandler.obtainMessage(
14565 ENABLE_ROLLBACK_TIMEOUT);
14566 msg.arg1 = enableRollbackToken;
14567 msg.arg2 = mSessionId;
14568 mHandler.sendMessageDelayed(msg, rollbackTimeout);
14570 }, null, 0, null, null);
14572 mEnableRollbackCompleted = false;
14580 * Send a request to check the integrity of the package.
14582 void sendIntegrityVerificationRequest(
14583 int verificationId,
14584 PackageInfoLite pkgLite,
14585 PackageVerificationState verificationState) {
14586 if (!isIntegrityVerificationEnabled()) {
14587 // Consider the integrity check as passed.
14588 verificationState.setIntegrityVerificationResult(
14589 PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
14593 final Intent integrityVerification =
14594 new Intent(Intent.ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
14596 integrityVerification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14597 PACKAGE_MIME_TYPE);
14599 final int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
14600 | Intent.FLAG_RECEIVER_REGISTERED_ONLY
14601 | Intent.FLAG_RECEIVER_FOREGROUND;
14602 integrityVerification.addFlags(flags);
14604 integrityVerification.putExtra(EXTRA_VERIFICATION_ID, verificationId);
14605 integrityVerification.putExtra(EXTRA_PACKAGE_NAME, pkgLite.packageName);
14606 integrityVerification.putExtra(EXTRA_VERSION_CODE, pkgLite.versionCode);
14607 integrityVerification.putExtra(EXTRA_LONG_VERSION_CODE, pkgLite.getLongVersionCode());
14608 populateInstallerExtras(integrityVerification);
14610 // send to integrity component only.
14611 integrityVerification.setPackage("android");
14613 DeviceIdleInternal idleController =
14614 mInjector.getLocalDeviceIdleController();
14615 final long idleDuration = getVerificationTimeout();
14617 idleController.addPowerSaveTempWhitelistAppDirect(Process.myUid(),
14619 false, "integrity component");
14620 mContext.sendOrderedBroadcastAsUser(integrityVerification, UserHandle.SYSTEM,
14621 /* receiverPermission= */ null,
14622 new BroadcastReceiver() {
14624 public void onReceive(Context context, Intent intent) {
14625 final Message msg =
14626 mHandler.obtainMessage(CHECK_PENDING_INTEGRITY_VERIFICATION);
14627 msg.arg1 = verificationId;
14628 // TODO: do we want to use the same timeout?
14629 mHandler.sendMessageDelayed(msg, getVerificationTimeout());
14631 }, /* scheduler= */ null,
14632 /* initialCode= */ 0,
14633 /* initialData= */ null,
14634 /* initialExtras= */ null);
14636 Trace.asyncTraceBegin(
14637 TRACE_TAG_PACKAGE_MANAGER, "integrity_verification", verificationId);
14639 // stop the copy until verification succeeds.
14640 mIntegrityVerificationCompleted = false;
14644 * Send a request to verifier(s) to verify the package if necessary, and return
14645 * {@link PackageManager#INSTALL_SUCCEEDED} if succeeded.
14647 int sendPackageVerificationRequest(
14648 int verificationId,
14649 PackageInfoLite pkgLite,
14650 PackageVerificationState verificationState) {
14651 int ret = INSTALL_SUCCEEDED;
14653 // TODO: http://b/22976637
14654 // Apps installed for "all" users use the device owner to verify the app
14655 UserHandle verifierUser = getUser();
14656 if (verifierUser == UserHandle.ALL) {
14657 verifierUser = UserHandle.SYSTEM;
14661 * Determine if we have any installed package verifiers. If we
14662 * do, then we'll defer to them to verify the packages.
14664 final int requiredUid = mRequiredVerifierPackage == null ? -1
14665 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
14666 verifierUser.getIdentifier());
14667 verificationState.setRequiredVerifierUid(requiredUid);
14668 final int installerUid =
14669 verificationInfo == null ? -1 : verificationInfo.installerUid;
14670 if (!origin.existing && requiredUid != -1
14671 && isVerificationEnabled(
14672 pkgLite, verifierUser.getIdentifier(), installFlags, installerUid)) {
14673 final Intent verification = new Intent(
14674 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
14675 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14676 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14677 PACKAGE_MIME_TYPE);
14678 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14680 // Query all live verifiers based on current user state
14681 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
14682 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
14683 false /*allowDynamicSplits*/);
14685 if (DEBUG_VERIFY) {
14686 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
14687 + verification.toString() + " with " + pkgLite.verifiers.length
14688 + " optional verifiers");
14691 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14693 verification.putExtra(
14694 PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, installFlags);
14696 verification.putExtra(
14697 PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, pkgLite.packageName);
14699 verification.putExtra(
14700 PackageManager.EXTRA_VERIFICATION_VERSION_CODE, pkgLite.versionCode);
14702 verification.putExtra(
14703 PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
14704 pkgLite.getLongVersionCode());
14706 populateInstallerExtras(verification);
14708 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
14709 receivers, verificationState);
14711 DeviceIdleInternal idleController =
14712 mInjector.getLocalDeviceIdleController();
14713 final long idleDuration = getVerificationTimeout();
14716 * If any sufficient verifiers were listed in the package
14717 * manifest, attempt to ask them.
14719 if (sufficientVerifiers != null) {
14720 final int n = sufficientVerifiers.size();
14722 Slog.i(TAG, "Additional verifiers required, but none installed.");
14723 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
14725 for (int i = 0; i < n; i++) {
14726 final ComponentName verifierComponent = sufficientVerifiers.get(i);
14727 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14728 verifierComponent.getPackageName(), idleDuration,
14729 verifierUser.getIdentifier(), false, "package verifier");
14731 final Intent sufficientIntent = new Intent(verification);
14732 sufficientIntent.setComponent(verifierComponent);
14733 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
14738 final ComponentName requiredVerifierComponent = matchComponentForVerifier(
14739 mRequiredVerifierPackage, receivers);
14740 if (mRequiredVerifierPackage != null) {
14742 * Send the intent to the required verification agent,
14743 * but only start the verification timeout after the
14744 * target BroadcastReceivers have run.
14746 verification.setComponent(requiredVerifierComponent);
14747 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14748 mRequiredVerifierPackage, idleDuration,
14749 verifierUser.getIdentifier(), false, "package verifier");
14750 mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
14751 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14752 new BroadcastReceiver() {
14754 public void onReceive(Context context, Intent intent) {
14755 final Message msg = mHandler
14756 .obtainMessage(CHECK_PENDING_VERIFICATION);
14757 msg.arg1 = verificationId;
14758 mHandler.sendMessageDelayed(msg, getVerificationTimeout());
14760 }, null, 0, null, null);
14762 Trace.asyncTraceBegin(
14763 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
14766 * We don't want the copy to proceed until verification
14769 mVerificationCompleted = false;
14772 verificationState.setVerifierResponse(
14773 requiredUid, PackageManager.VERIFICATION_ALLOW);
14778 void populateInstallerExtras(Intent intent) {
14779 intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
14780 installSource.initiatingPackageName);
14782 if (verificationInfo != null) {
14783 if (verificationInfo.originatingUri != null) {
14784 intent.putExtra(Intent.EXTRA_ORIGINATING_URI,
14785 verificationInfo.originatingUri);
14787 if (verificationInfo.referrer != null) {
14788 intent.putExtra(Intent.EXTRA_REFERRER,
14789 verificationInfo.referrer);
14791 if (verificationInfo.originatingUid >= 0) {
14792 intent.putExtra(Intent.EXTRA_ORIGINATING_UID,
14793 verificationInfo.originatingUid);
14795 if (verificationInfo.installerUid >= 0) {
14796 intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
14797 verificationInfo.installerUid);
14802 void setReturnCode(int ret) {
14803 if (mRet == PackageManager.INSTALL_SUCCEEDED) {
14804 // Only update mRet if it was previously INSTALL_SUCCEEDED to
14805 // ensure we do not overwrite any previous failure results.
14810 void handleVerificationFinished() {
14811 if (!mVerificationCompleted) {
14812 mVerificationCompleted = true;
14813 if (mIntegrityVerificationCompleted) {
14814 handleReturnCode();
14816 // integrity verification still pending.
14820 void handleIntegrityVerificationFinished() {
14821 if (!mIntegrityVerificationCompleted) {
14822 mIntegrityVerificationCompleted = true;
14823 if (mVerificationCompleted) {
14824 handleReturnCode();
14826 // verifier still pending
14831 void handleRollbackEnabled() {
14832 // TODO(ruhler) b/112431924: Consider halting the install if we
14833 // couldn't enable rollback.
14834 mEnableRollbackCompleted = true;
14835 handleReturnCode();
14839 void handleReturnCode() {
14840 if (mVerificationCompleted
14841 && mIntegrityVerificationCompleted && mEnableRollbackCompleted) {
14842 if ((installFlags & PackageManager.INSTALL_DRY_RUN) != 0) {
14843 String packageName = "";
14845 PackageLite packageInfo =
14846 new PackageParser().parsePackageLite(origin.file, 0);
14847 packageName = packageInfo.packageName;
14848 } catch (PackageParserException e) {
14849 Slog.e(TAG, "Can't parse package at " + origin.file.getAbsolutePath(), e);
14852 observer.onPackageInstalled(packageName, mRet, "Dry run", new Bundle());
14853 } catch (RemoteException e) {
14854 Slog.i(TAG, "Observer no longer exists.");
14858 if (mRet == PackageManager.INSTALL_SUCCEEDED) {
14859 mRet = mArgs.copyApk();
14861 processPendingInstall(mArgs, mRet);
14866 private InstallArgs createInstallArgs(InstallParams params) {
14867 if (params.move != null) {
14868 return new MoveInstallArgs(params);
14870 return new FileInstallArgs(params);
14875 * Create args that describe an existing installed package. Typically used
14876 * when cleaning up old installs, or used as a move source.
14878 private InstallArgs createInstallArgsForExisting(String codePath,
14879 String resourcePath, String[] instructionSets) {
14880 return new FileInstallArgs(codePath, resourcePath, instructionSets);
14883 static abstract class InstallArgs {
14884 /** @see InstallParams#origin */
14885 final OriginInfo origin;
14886 /** @see InstallParams#move */
14887 final MoveInfo move;
14889 final IPackageInstallObserver2 observer;
14890 // Always refers to PackageManager flags only
14891 final int installFlags;
14892 @NonNull final InstallSource installSource;
14893 final String volumeUuid;
14894 final UserHandle user;
14895 final String abiOverride;
14896 final String[] installGrantPermissions;
14897 final List<String> whitelistedRestrictedPermissions;
14898 /** If non-null, drop an async trace when the install completes */
14899 final String traceMethod;
14900 final int traceCookie;
14901 final PackageParser.SigningDetails signingDetails;
14902 final int installReason;
14903 final boolean forceQueryableOverride;
14904 @Nullable final MultiPackageInstallParams mMultiPackageInstallParams;
14905 final int mDataLoaderType;
14907 // The list of instruction sets supported by this app. This is currently
14908 // only used during the rmdex() phase to clean up resources. We can get rid of this
14909 // if we move dex files under the common app path.
14910 /* nullable */ String[] instructionSets;
14912 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14913 int installFlags, InstallSource installSource, String volumeUuid,
14914 UserHandle user, String[] instructionSets,
14915 String abiOverride, String[] installGrantPermissions,
14916 List<String> whitelistedRestrictedPermissions,
14917 String traceMethod, int traceCookie, SigningDetails signingDetails,
14918 int installReason, boolean forceQueryableOverride,
14919 MultiPackageInstallParams multiPackageInstallParams, int dataLoaderType) {
14920 this.origin = origin;
14922 this.installFlags = installFlags;
14923 this.observer = observer;
14924 this.installSource = Preconditions.checkNotNull(installSource);
14925 this.volumeUuid = volumeUuid;
14927 this.instructionSets = instructionSets;
14928 this.abiOverride = abiOverride;
14929 this.installGrantPermissions = installGrantPermissions;
14930 this.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
14931 this.traceMethod = traceMethod;
14932 this.traceCookie = traceCookie;
14933 this.signingDetails = signingDetails;
14934 this.installReason = installReason;
14935 this.forceQueryableOverride = forceQueryableOverride;
14936 this.mMultiPackageInstallParams = multiPackageInstallParams;
14937 this.mDataLoaderType = dataLoaderType;
14941 InstallArgs(InstallParams params) {
14942 this(params.origin, params.move, params.observer, params.installFlags,
14943 params.installSource, params.volumeUuid,
14944 params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
14945 params.grantedRuntimePermissions, params.whitelistedRestrictedPermissions,
14946 params.traceMethod, params.traceCookie, params.signingDetails,
14947 params.installReason, params.forceQueryableOverride,
14948 params.mParentInstallParams, params.mDataLoaderType);
14951 abstract int copyApk();
14952 abstract int doPreInstall(int status);
14955 * Rename package into final resting place. All paths on the given
14956 * scanned package should be updated to reflect the rename.
14958 abstract boolean doRename(int status, ParsedPackage parsedPackage);
14959 abstract int doPostInstall(int status, int uid);
14961 /** @see PackageSettingBase#codePathString */
14962 abstract String getCodePath();
14963 /** @see PackageSettingBase#resourcePathString */
14964 abstract String getResourcePath();
14966 // Need installer lock especially for dex file removal.
14967 abstract void cleanUpResourcesLI();
14968 abstract boolean doPostDeleteLI(boolean delete);
14971 * Called before the source arguments are copied. This is used mostly
14972 * for MoveParams when it needs to read the source file to put it in the
14976 return PackageManager.INSTALL_SUCCEEDED;
14980 * Called after the source arguments are copied. This is used mostly for
14981 * MoveParams when it needs to read the source file to put it in the
14984 int doPostCopy(int uid) {
14985 return PackageManager.INSTALL_SUCCEEDED;
14988 protected boolean isEphemeral() {
14989 return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14992 UserHandle getUser() {
14997 void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
14998 if (!allCodePaths.isEmpty()) {
14999 if (instructionSets == null) {
15000 throw new IllegalStateException("instructionSet == null");
15002 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15003 for (String codePath : allCodePaths) {
15004 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15006 mInstaller.rmdex(codePath, dexCodeInstructionSet);
15007 } catch (InstallerException ignored) {
15015 * Logic to handle installation of new applications, including copying
15016 * and renaming logic.
15018 class FileInstallArgs extends InstallArgs {
15019 private File codeFile;
15020 private File resourceFile;
15022 // Example topology:
15023 // /data/app/com.example/base.apk
15024 // /data/app/com.example/split_foo.apk
15025 // /data/app/com.example/lib/arm/libfoo.so
15026 // /data/app/com.example/lib/arm64/libfoo.so
15027 // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15030 FileInstallArgs(InstallParams params) {
15034 /** Existing install */
15035 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15036 super(OriginInfo.fromNothing(), null, null, 0, InstallSource.EMPTY,
15037 null, null, instructionSets, null, null, null, null, 0,
15038 PackageParser.SigningDetails.UNKNOWN,
15039 PackageManager.INSTALL_REASON_UNKNOWN, false, null /* parent */,
15040 DataLoaderType.NONE);
15041 this.codeFile = (codePath != null) ? new File(codePath) : null;
15042 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15046 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15048 return doCopyApk();
15050 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15054 private int doCopyApk() {
15055 if (origin.staged) {
15056 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15057 codeFile = origin.file;
15058 resourceFile = origin.file;
15059 return PackageManager.INSTALL_SUCCEEDED;
15063 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15064 final File tempDir =
15065 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15066 codeFile = tempDir;
15067 resourceFile = tempDir;
15068 } catch (IOException e) {
15069 Slog.w(TAG, "Failed to create copy file: " + e);
15070 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15073 int ret = PackageManagerServiceUtils.copyPackage(
15074 origin.file.getAbsolutePath(), codeFile);
15075 if (ret != PackageManager.INSTALL_SUCCEEDED) {
15076 Slog.e(TAG, "Failed to copy package");
15080 final boolean isIncremental = isIncrementalPath(codeFile.getAbsolutePath());
15081 final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15082 NativeLibraryHelper.Handle handle = null;
15084 handle = NativeLibraryHelper.Handle.create(codeFile);
15085 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15086 abiOverride, isIncremental);
15087 } catch (IOException e) {
15088 Slog.e(TAG, "Copying native libraries failed", e);
15089 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15091 IoUtils.closeQuietly(handle);
15097 int doPreInstall(int status) {
15098 if (status != PackageManager.INSTALL_SUCCEEDED) {
15105 boolean doRename(int status, ParsedPackage parsedPackage) {
15106 if (status != PackageManager.INSTALL_SUCCEEDED) {
15111 final File targetDir = codeFile.getParentFile();
15112 final File beforeCodeFile = codeFile;
15113 final File afterCodeFile = getNextCodePath(targetDir, parsedPackage.getPackageName());
15115 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15116 final boolean onIncremental = mIncrementalManager != null
15117 && isIncrementalPath(beforeCodeFile.getAbsolutePath());
15119 makeDirRecursive(afterCodeFile.getParentFile(), 0775);
15120 if (onIncremental) {
15121 mIncrementalManager.renameCodePath(beforeCodeFile, afterCodeFile);
15123 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15125 } catch (IOException | ErrnoException e) {
15126 Slog.w(TAG, "Failed to rename", e);
15130 //TODO(b/136132412): enable selinux restorecon for incremental directories
15131 if (!onIncremental && !SELinux.restoreconRecursive(afterCodeFile)) {
15132 Slog.w(TAG, "Failed to restorecon");
15136 // Reflect the rename internally
15137 codeFile = afterCodeFile;
15138 resourceFile = afterCodeFile;
15140 // Reflect the rename in scanned details
15142 parsedPackage.setCodePath(afterCodeFile.getCanonicalPath());
15143 } catch (IOException e) {
15144 Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
15147 parsedPackage.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15148 afterCodeFile, parsedPackage.getBaseCodePath()));
15149 parsedPackage.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15150 afterCodeFile, parsedPackage.getSplitCodePaths()));
15155 int doPostInstall(int status, int uid) {
15156 if (status != PackageManager.INSTALL_SUCCEEDED) {
15163 String getCodePath() {
15164 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15168 String getResourcePath() {
15169 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15172 private boolean cleanUp() {
15173 if (codeFile == null || !codeFile.exists()) {
15177 String codePath = codeFile.getAbsolutePath();
15178 if (mIncrementalManager != null && isIncrementalPath(codePath)) {
15179 mIncrementalManager.closeStorage(codePath);
15182 removeCodePathLI(codeFile);
15184 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15185 resourceFile.delete();
15191 void cleanUpResourcesLI() {
15192 // Try enumerating all code paths before deleting
15193 List<String> allCodePaths = Collections.EMPTY_LIST;
15194 if (codeFile != null && codeFile.exists()) {
15196 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15197 allCodePaths = pkg.getAllCodePaths();
15198 } catch (PackageParserException e) {
15199 // Ignored; we tried our best
15204 removeDexFiles(allCodePaths, instructionSets);
15207 boolean doPostDeleteLI(boolean delete) {
15208 // XXX err, shouldn't we respect the delete flag?
15209 cleanUpResourcesLI();
15215 * Logic to handle movement of existing installed applications.
15217 class MoveInstallArgs extends InstallArgs {
15218 private File codeFile;
15219 private File resourceFile;
15222 MoveInstallArgs(InstallParams params) {
15227 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15228 + move.fromUuid + " to " + move.toUuid);
15229 synchronized (mInstaller) {
15231 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15232 move.appId, move.seinfo, move.targetSdkVersion,
15233 move.fromCodePath);
15234 } catch (InstallerException e) {
15235 Slog.w(TAG, "Failed to move app", e);
15236 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15240 final String toPathName = new File(move.fromCodePath).getName();
15241 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), toPathName);
15242 resourceFile = codeFile;
15243 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15245 return PackageManager.INSTALL_SUCCEEDED;
15248 int doPreInstall(int status) {
15249 if (status != PackageManager.INSTALL_SUCCEEDED) {
15250 cleanUp(move.toUuid);
15256 boolean doRename(int status, ParsedPackage parsedPackage) {
15257 if (status != PackageManager.INSTALL_SUCCEEDED) {
15258 cleanUp(move.toUuid);
15265 int doPostInstall(int status, int uid) {
15266 if (status == PackageManager.INSTALL_SUCCEEDED) {
15267 cleanUp(move.fromUuid);
15269 cleanUp(move.toUuid);
15275 String getCodePath() {
15276 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15280 String getResourcePath() {
15281 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15284 private boolean cleanUp(String volumeUuid) {
15285 final String toPathName = new File(move.fromCodePath).getName();
15286 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15288 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15289 final int[] userIds = mUserManager.getUserIds();
15290 synchronized (mInstallLock) {
15291 // Clean up both app data and code
15292 // All package moves are frozen until finished
15294 // We purposefully exclude FLAG_STORAGE_EXTERNAL here, since
15295 // this task was only focused on moving data on internal storage.
15296 // We don't want ART profiles cleared, because they don't move,
15297 // so we would be deleting the only copy (b/149200535).
15298 final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE
15299 | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES;
15300 for (int userId : userIds) {
15302 mInstaller.destroyAppData(volumeUuid, move.packageName, userId, flags, 0);
15303 } catch (InstallerException e) {
15304 Slog.w(TAG, String.valueOf(e));
15307 removeCodePathLI(codeFile);
15312 void cleanUpResourcesLI() {
15313 throw new UnsupportedOperationException();
15316 boolean doPostDeleteLI(boolean delete) {
15317 throw new UnsupportedOperationException();
15322 * Given {@code targetDir}, returns {@code targetDir/~~[randomStrA]/[packageName]-[randomStrB].}
15323 * Makes sure that {@code targetDir/~~[randomStrA]} directory doesn't exist.
15324 * Notice that this method doesn't actually create any directory.
15326 * @param targetDir Directory that is two-levels up from the result directory.
15327 * @param packageName Name of the package whose code files are to be installed under the result
15329 * @return File object for the directory that should hold the code files of {@code packageName}.
15331 private File getNextCodePath(File targetDir, String packageName) {
15332 SecureRandom random = new SecureRandom();
15333 byte[] bytes = new byte[16];
15334 File firstLevelDir;
15336 random.nextBytes(bytes);
15337 String dirName = RANDOM_DIR_PREFIX
15338 + Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15339 firstLevelDir = new File(targetDir, dirName);
15340 } while (firstLevelDir.exists());
15341 random.nextBytes(bytes);
15342 String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15343 return new File(firstLevelDir, packageName + "-" + suffix);
15346 static class PackageInstalledInfo {
15349 // The set of users that originally had this package installed.
15351 // The set of users that now have this package installed.
15353 AndroidPackage pkg;
15356 String installerPackageName;
15357 PackageRemovedInfo removedInfo;
15358 ArrayMap<String, PackageInstalledInfo> addedChildPackages;
15359 // The set of packages consuming this shared library or null if no consumers exist.
15360 ArrayList<AndroidPackage> libraryConsumers;
15361 PackageFreezer freezer;
15363 public void setError(int code, String msg) {
15364 setReturnCode(code);
15365 setReturnMessage(msg);
15369 public void setError(String msg, PackageParserException e) {
15370 setReturnCode(e.error);
15371 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15372 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15373 for (int i = 0; i < childCount; i++) {
15374 addedChildPackages.valueAt(i).setError(msg, e);
15376 Slog.w(TAG, msg, e);
15379 public void setError(String msg, PackageManagerException e) {
15380 returnCode = e.error;
15381 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15382 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15383 for (int i = 0; i < childCount; i++) {
15384 addedChildPackages.valueAt(i).setError(msg, e);
15386 Slog.w(TAG, msg, e);
15389 public void setReturnCode(int returnCode) {
15390 this.returnCode = returnCode;
15391 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15392 for (int i = 0; i < childCount; i++) {
15393 addedChildPackages.valueAt(i).returnCode = returnCode;
15397 private void setReturnMessage(String returnMsg) {
15398 this.returnMsg = returnMsg;
15399 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15400 for (int i = 0; i < childCount; i++) {
15401 addedChildPackages.valueAt(i).returnMsg = returnMsg;
15405 // In some error cases we want to convey more info back to the observer
15406 String origPackage;
15407 String origPermission;
15410 private static void updateDigest(MessageDigest digest, File file) throws IOException {
15411 try (DigestInputStream digestStream =
15412 new DigestInputStream(new FileInputStream(file), digest)) {
15413 while (digestStream.read() != -1) {} // nothing to do; just plow through the file
15417 private void removeNativeBinariesLI(PackageSetting ps) {
15419 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
15423 @GuardedBy("mLock")
15424 private void enableSystemPackageLPw(AndroidPackage pkg) {
15425 mSettings.enableSystemPackageLPw(pkg.getPackageName());
15428 @GuardedBy("mLock")
15429 private boolean disableSystemPackageLPw(AndroidPackage oldPkg) {
15430 return mSettings.disableSystemPackageLPw(oldPkg.getPackageName(), true);
15433 private void updateSettingsLI(AndroidPackage newPackage, InstallArgs installArgs,
15434 int[] allUsers, PackageInstalledInfo res) {
15435 updateSettingsInternalLI(newPackage, installArgs, allUsers, res);
15438 private void updateSettingsInternalLI(AndroidPackage pkg, InstallArgs installArgs,
15439 int[] allUsers, PackageInstalledInfo res) {
15440 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
15442 final String pkgName = pkg.getPackageName();
15443 final int[] installedForUsers = res.origUsers;
15444 final int installReason = installArgs.installReason;
15445 InstallSource installSource = installArgs.installSource;
15446 final String installerPackageName = installSource.installerPackageName;
15448 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.getCodePath());
15449 synchronized (mLock) {
15450 // NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
15451 mPermissionManager.updatePermissions(pkgName, pkg);
15452 // For system-bundled packages, we assume that installing an upgraded version
15453 // of the package implies that the user actually wants to run that new code,
15454 // so we enable the package.
15455 final PackageSetting ps = mSettings.mPackages.get(pkgName);
15456 final int userId = installArgs.user.getIdentifier();
15458 if (pkg.isSystem()) {
15459 if (DEBUG_INSTALL) {
15460 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
15462 // Enable system package for requested users
15463 if (res.origUsers != null) {
15464 for (int origUserId : res.origUsers) {
15465 if (userId == UserHandle.USER_ALL || userId == origUserId) {
15466 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
15467 origUserId, installerPackageName);
15471 // Also convey the prior install/uninstall state
15472 if (allUsers != null && installedForUsers != null) {
15473 for (int currentUserId : allUsers) {
15474 final boolean installed = ArrayUtils.contains(
15475 installedForUsers, currentUserId);
15476 if (DEBUG_INSTALL) {
15477 Slog.d(TAG, " user " + currentUserId + " => " + installed);
15479 ps.setInstalled(installed, currentUserId);
15481 // these install state changes will be persisted in the
15482 // upcoming call to mSettings.writeLPr().
15486 // Retrieve the overlays for shared libraries of the package.
15487 if (!ps.getPkgState().getUsesLibraryInfos().isEmpty()) {
15488 for (SharedLibraryInfo sharedLib : ps.getPkgState().getUsesLibraryInfos()) {
15489 for (int currentUserId : UserManagerService.getInstance().getUserIds()) {
15490 if (!sharedLib.isDynamic()) {
15491 // TODO(146804378): Support overlaying static shared libraries
15494 final PackageSetting libPs = mSettings.mPackages.get(
15495 sharedLib.getPackageName());
15496 if (libPs == null) {
15499 final String[] overlayPaths = libPs.getOverlayPaths(currentUserId);
15500 if (overlayPaths != null) {
15501 ps.setOverlayPathsForLibrary(sharedLib.getName(),
15502 Arrays.asList(overlayPaths), currentUserId);
15508 // It's implied that when a user requests installation, they want the app to be
15509 // installed and enabled.
15510 if (userId != UserHandle.USER_ALL) {
15511 ps.setInstalled(true, userId);
15512 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
15515 if (installSource.initiatingPackageName != null) {
15516 final PackageSetting ips = mSettings.mPackages.get(
15517 installSource.initiatingPackageName);
15519 installSource = installSource.setInitiatingPackageSignatures(
15523 ps.setInstallSource(installSource);
15524 mSettings.addInstallerPackageNames(installSource);
15526 // When replacing an existing package, preserve the original install reason for all
15527 // users that had the package installed before.
15528 final Set<Integer> previousUserIds = new ArraySet<>();
15529 if (res.removedInfo != null && res.removedInfo.installReasons != null) {
15530 final int installReasonCount = res.removedInfo.installReasons.size();
15531 for (int i = 0; i < installReasonCount; i++) {
15532 final int previousUserId = res.removedInfo.installReasons.keyAt(i);
15533 final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
15534 ps.setInstallReason(previousInstallReason, previousUserId);
15535 previousUserIds.add(previousUserId);
15539 // Set install reason for users that are having the package newly installed.
15540 if (userId == UserHandle.USER_ALL) {
15541 for (int currentUserId : mUserManager.getUserIds()) {
15542 if (!previousUserIds.contains(currentUserId)) {
15543 ps.setInstallReason(installReason, currentUserId);
15546 } else if (!previousUserIds.contains(userId)) {
15547 ps.setInstallReason(installReason, userId);
15549 mSettings.writeKernelMappingLPr(ps);
15551 res.name = pkgName;
15552 res.uid = pkg.getUid();
15554 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
15555 //to update install status
15556 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
15557 mSettings.writeLPr();
15558 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15561 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15564 private static class InstallRequest {
15565 public final InstallArgs args;
15566 public final PackageInstalledInfo installResult;
15568 private InstallRequest(InstallArgs args, PackageInstalledInfo res) {
15570 this.installResult = res;
15574 @GuardedBy({"mInstallLock", "mLock"})
15575 private void installPackagesTracedLI(List<InstallRequest> requests) {
15577 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages");
15578 installPackagesLI(requests);
15580 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15585 * Package state to commit to memory and disk after reconciliation has completed.
15587 private static class CommitRequest {
15588 final Map<String, ReconciledPackage> reconciledPackages;
15589 final int[] mAllUsers;
15591 private CommitRequest(Map<String, ReconciledPackage> reconciledPackages, int[] allUsers) {
15592 this.reconciledPackages = reconciledPackages;
15593 this.mAllUsers = allUsers;
15598 * Package scan results and related request details used to reconcile the potential addition of
15599 * one or more packages to the system.
15601 * Reconcile will take a set of package details that need to be committed to the system and make
15602 * sure that they are valid in the context of the system and the other installing apps. Any
15603 * invalid state or app will result in a failed reconciliation and thus whatever operation (such
15604 * as install) led to the request.
15606 private static class ReconcileRequest {
15607 public final Map<String, ScanResult> scannedPackages;
15609 public final Map<String, AndroidPackage> allPackages;
15610 public final Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource;
15611 public final Map<String, InstallArgs> installArgs;
15612 public final Map<String, PackageInstalledInfo> installResults;
15613 public final Map<String, PrepareResult> preparedPackages;
15614 public final Map<String, VersionInfo> versionInfos;
15615 public final Map<String, PackageSetting> lastStaticSharedLibSettings;
15617 private ReconcileRequest(Map<String, ScanResult> scannedPackages,
15618 Map<String, InstallArgs> installArgs,
15619 Map<String, PackageInstalledInfo> installResults,
15620 Map<String, PrepareResult> preparedPackages,
15621 Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource,
15622 Map<String, AndroidPackage> allPackages,
15623 Map<String, VersionInfo> versionInfos,
15624 Map<String, PackageSetting> lastStaticSharedLibSettings) {
15625 this.scannedPackages = scannedPackages;
15626 this.installArgs = installArgs;
15627 this.installResults = installResults;
15628 this.preparedPackages = preparedPackages;
15629 this.sharedLibrarySource = sharedLibrarySource;
15630 this.allPackages = allPackages;
15631 this.versionInfos = versionInfos;
15632 this.lastStaticSharedLibSettings = lastStaticSharedLibSettings;
15635 private ReconcileRequest(Map<String, ScanResult> scannedPackages,
15636 Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource,
15637 Map<String, AndroidPackage> allPackages,
15638 Map<String, VersionInfo> versionInfos,
15639 Map<String, PackageSetting> lastStaticSharedLibSettings) {
15640 this(scannedPackages, Collections.emptyMap(), Collections.emptyMap(),
15641 Collections.emptyMap(), sharedLibrarySource, allPackages, versionInfos,
15642 lastStaticSharedLibSettings);
15645 private static class ReconcileFailure extends PackageManagerException {
15646 ReconcileFailure(String message) {
15647 super("Reconcile failed: " + message);
15649 ReconcileFailure(int reason, String message) {
15650 super(reason, "Reconcile failed: " + message);
15652 ReconcileFailure(PackageManagerException e) {
15653 this(e.error, e.getMessage());
15658 * A container of all data needed to commit a package to in-memory data structures and to disk.
15659 * TODO: move most of the data contained her into a PackageSetting for commit.
15661 private static class ReconciledPackage {
15662 public final ReconcileRequest request;
15663 public final PackageSetting pkgSetting;
15664 public final ScanResult scanResult;
15665 // TODO: Remove install-specific details from the reconcile result
15666 public final PackageInstalledInfo installResult;
15667 @Nullable public final PrepareResult prepareResult;
15668 @Nullable public final InstallArgs installArgs;
15669 public final DeletePackageAction deletePackageAction;
15670 public final List<SharedLibraryInfo> allowedSharedLibraryInfos;
15671 public final SigningDetails signingDetails;
15672 public final boolean sharedUserSignaturesChanged;
15673 public ArrayList<SharedLibraryInfo> collectedSharedLibraryInfos;
15674 public final boolean removeAppKeySetData;
15676 private ReconciledPackage(ReconcileRequest request,
15677 InstallArgs installArgs,
15678 PackageSetting pkgSetting,
15679 PackageInstalledInfo installResult,
15680 PrepareResult prepareResult,
15681 ScanResult scanResult,
15682 DeletePackageAction deletePackageAction,
15683 List<SharedLibraryInfo> allowedSharedLibraryInfos,
15684 SigningDetails signingDetails,
15685 boolean sharedUserSignaturesChanged,
15686 boolean removeAppKeySetData) {
15687 this.request = request;
15688 this.installArgs = installArgs;
15689 this.pkgSetting = pkgSetting;
15690 this.installResult = installResult;
15691 this.prepareResult = prepareResult;
15692 this.scanResult = scanResult;
15693 this.deletePackageAction = deletePackageAction;
15694 this.allowedSharedLibraryInfos = allowedSharedLibraryInfos;
15695 this.signingDetails = signingDetails;
15696 this.sharedUserSignaturesChanged = sharedUserSignaturesChanged;
15697 this.removeAppKeySetData = removeAppKeySetData;
15701 * Returns a combined set of packages containing the packages already installed combined
15702 * with the package(s) currently being installed. The to-be installed packages take
15703 * precedence and may shadow already installed packages.
15705 private Map<String, AndroidPackage> getCombinedAvailablePackages() {
15706 final ArrayMap<String, AndroidPackage> combined =
15707 new ArrayMap<>(request.allPackages.size() + request.scannedPackages.size());
15709 combined.putAll(request.allPackages);
15711 for (ScanResult scanResult : request.scannedPackages.values()) {
15712 combined.put(scanResult.pkgSetting.name, scanResult.request.parsedPackage);
15719 @GuardedBy("mLock")
15720 private static Map<String, ReconciledPackage> reconcilePackagesLocked(
15721 final ReconcileRequest request, KeySetManagerService ksms)
15722 throws ReconcileFailure {
15723 final Map<String, ScanResult> scannedPackages = request.scannedPackages;
15725 final Map<String, ReconciledPackage> result = new ArrayMap<>(scannedPackages.size());
15727 // make a copy of the existing set of packages so we can combine them with incoming packages
15728 final ArrayMap<String, AndroidPackage> combinedPackages =
15729 new ArrayMap<>(request.allPackages.size() + scannedPackages.size());
15731 combinedPackages.putAll(request.allPackages);
15733 final Map<String, LongSparseArray<SharedLibraryInfo>> incomingSharedLibraries =
15736 for (String installPackageName : scannedPackages.keySet()) {
15737 final ScanResult scanResult = scannedPackages.get(installPackageName);
15739 // add / replace existing with incoming packages
15740 combinedPackages.put(scanResult.pkgSetting.name, scanResult.request.parsedPackage);
15742 // in the first pass, we'll build up the set of incoming shared libraries
15743 final List<SharedLibraryInfo> allowedSharedLibInfos =
15744 getAllowedSharedLibInfos(scanResult, request.sharedLibrarySource);
15745 final SharedLibraryInfo staticLib = scanResult.staticSharedLibraryInfo;
15746 if (allowedSharedLibInfos != null) {
15747 for (SharedLibraryInfo info : allowedSharedLibInfos) {
15748 if (!addSharedLibraryToPackageVersionMap(incomingSharedLibraries, info)) {
15749 throw new ReconcileFailure("Static Shared Library " + staticLib.getName()
15750 + " is being installed twice in this set!");
15755 // the following may be null if we're just reconciling on boot (and not during install)
15756 final InstallArgs installArgs = request.installArgs.get(installPackageName);
15757 final PackageInstalledInfo res = request.installResults.get(installPackageName);
15758 final PrepareResult prepareResult = request.preparedPackages.get(installPackageName);
15759 final boolean isInstall = installArgs != null;
15760 if (isInstall && (res == null || prepareResult == null)) {
15761 throw new ReconcileFailure("Reconcile arguments are not balanced for "
15762 + installPackageName + "!");
15765 final DeletePackageAction deletePackageAction;
15766 // we only want to try to delete for non system apps
15767 if (isInstall && prepareResult.replace && !prepareResult.system) {
15768 final boolean killApp = (scanResult.request.scanFlags & SCAN_DONT_KILL_APP) == 0;
15769 final int deleteFlags = PackageManager.DELETE_KEEP_DATA
15770 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
15771 deletePackageAction = mayDeletePackageLocked(res.removedInfo,
15772 prepareResult.originalPs, prepareResult.disabledPs,
15773 deleteFlags, null /* all users */);
15774 if (deletePackageAction == null) {
15775 throw new ReconcileFailure(
15776 PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE,
15777 "May not delete " + installPackageName + " to replace");
15780 deletePackageAction = null;
15783 final int scanFlags = scanResult.request.scanFlags;
15784 final int parseFlags = scanResult.request.parseFlags;
15785 final ParsedPackage parsedPackage = scanResult.request.parsedPackage;
15787 final PackageSetting disabledPkgSetting = scanResult.request.disabledPkgSetting;
15788 final PackageSetting lastStaticSharedLibSetting =
15789 request.lastStaticSharedLibSettings.get(installPackageName);
15790 final PackageSetting signatureCheckPs =
15791 (prepareResult != null && lastStaticSharedLibSetting != null)
15792 ? lastStaticSharedLibSetting
15793 : scanResult.pkgSetting;
15794 boolean removeAppKeySetData = false;
15795 boolean sharedUserSignaturesChanged = false;
15796 SigningDetails signingDetails = null;
15797 if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
15798 if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
15799 // We just determined the app is signed correctly, so bring
15800 // over the latest parsed certs.
15802 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
15803 throw new ReconcileFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15804 "Package " + parsedPackage.getPackageName()
15805 + " upgrade keys do not match the previously installed"
15808 String msg = "System package " + parsedPackage.getPackageName()
15809 + " signature changed; retaining data.";
15810 reportSettingsProblem(Log.WARN, msg);
15813 signingDetails = parsedPackage.getSigningDetails();
15816 final VersionInfo versionInfo = request.versionInfos.get(installPackageName);
15817 final boolean compareCompat = isCompatSignatureUpdateNeeded(versionInfo);
15818 final boolean compareRecover = isRecoverSignatureUpdateNeeded(versionInfo);
15819 final boolean compatMatch = verifySignatures(signatureCheckPs,
15820 disabledPkgSetting, parsedPackage.getSigningDetails(), compareCompat,
15822 // The new KeySets will be re-added later in the scanning process.
15824 removeAppKeySetData = true;
15826 // We just determined the app is signed correctly, so bring
15827 // over the latest parsed certs.
15828 signingDetails = parsedPackage.getSigningDetails();
15831 // if this is is a sharedUser, check to see if the new package is signed by a
15833 // signing certificate than the existing one, and if so, copy over the new
15835 if (signatureCheckPs.sharedUser != null) {
15836 if (parsedPackage.getSigningDetails().hasAncestor(
15837 signatureCheckPs.sharedUser.signatures.mSigningDetails)) {
15838 signatureCheckPs.sharedUser.signatures.mSigningDetails =
15839 parsedPackage.getSigningDetails();
15841 if (signatureCheckPs.sharedUser.signaturesChanged == null) {
15842 signatureCheckPs.sharedUser.signaturesChanged = Boolean.FALSE;
15845 } catch (PackageManagerException e) {
15846 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
15847 throw new ReconcileFailure(e);
15849 signingDetails = parsedPackage.getSigningDetails();
15851 // If the system app is part of a shared user we allow that shared user to
15853 // signatures as well as part of an OTA. We still need to verify that the
15855 // are consistent within the shared user for a given boot, so only allow
15857 // the signatures on the first package scanned for the shared user (i.e. if the
15858 // signaturesChanged state hasn't been initialized yet in SharedUserSetting).
15859 if (signatureCheckPs.sharedUser != null) {
15860 final Signature[] sharedUserSignatures =
15861 signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures;
15862 if (signatureCheckPs.sharedUser.signaturesChanged != null
15863 && compareSignatures(sharedUserSignatures,
15864 parsedPackage.getSigningDetails().signatures)
15865 != PackageManager.SIGNATURE_MATCH) {
15866 if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 29) {
15867 // Mismatched signatures is an error and silently skipping system
15868 // packages will likely break the device in unforeseen ways.
15869 // However, we allow the device to boot anyway because, prior to Q,
15870 // vendors were not expecting the platform to crash in this
15872 // This WILL be a hard failure on any new API levels after Q.
15873 throw new ReconcileFailure(
15874 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
15875 "Signature mismatch for shared user: "
15876 + scanResult.pkgSetting.sharedUser);
15878 // Treat mismatched signatures on system packages using a shared
15880 // fatal for the system overall, rather than just failing to install
15881 // whichever package happened to be scanned later.
15882 throw new IllegalStateException(
15883 "Signature mismatch on system package "
15884 + parsedPackage.getPackageName()
15885 + " for shared user "
15886 + scanResult.pkgSetting.sharedUser);
15890 sharedUserSignaturesChanged = true;
15891 signatureCheckPs.sharedUser.signatures.mSigningDetails =
15892 parsedPackage.getSigningDetails();
15893 signatureCheckPs.sharedUser.signaturesChanged = Boolean.TRUE;
15895 // File a report about this.
15896 String msg = "System package " + parsedPackage.getPackageName()
15897 + " signature changed; retaining data.";
15898 reportSettingsProblem(Log.WARN, msg);
15899 } catch (IllegalArgumentException e) {
15900 // should never happen: certs matched when checking, but not when comparing
15901 // old to new for sharedUser
15902 throw new RuntimeException(
15903 "Signing certificates comparison made on incomparable signing details"
15904 + " but somehow passed verifySignatures!", e);
15908 result.put(installPackageName,
15909 new ReconciledPackage(request, installArgs, scanResult.pkgSetting,
15910 res, request.preparedPackages.get(installPackageName), scanResult,
15911 deletePackageAction, allowedSharedLibInfos, signingDetails,
15912 sharedUserSignaturesChanged, removeAppKeySetData));
15915 for (String installPackageName : scannedPackages.keySet()) {
15916 // Check all shared libraries and map to their actual file path.
15917 // We only do this here for apps not on a system dir, because those
15918 // are the only ones that can fail an install due to this. We
15919 // will take care of the system apps by updating all of their
15920 // library paths after the scan is done. Also during the initial
15921 // scan don't update any libs as we do this wholesale after all
15922 // apps are scanned to avoid dependency based scanning.
15923 final ScanResult scanResult = scannedPackages.get(installPackageName);
15924 if ((scanResult.request.scanFlags & SCAN_BOOTING) != 0
15925 || (scanResult.request.parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
15929 result.get(installPackageName).collectedSharedLibraryInfos =
15930 collectSharedLibraryInfos(scanResult.request.parsedPackage,
15931 combinedPackages, request.sharedLibrarySource,
15932 incomingSharedLibraries);
15934 } catch (PackageManagerException e) {
15935 throw new ReconcileFailure(e.error, e.getMessage());
15943 * Compare the newly scanned package with current system state to see which of its declared
15944 * shared libraries should be allowed to be added to the system.
15946 private static List<SharedLibraryInfo> getAllowedSharedLibInfos(
15947 ScanResult scanResult,
15948 Map<String, LongSparseArray<SharedLibraryInfo>> existingSharedLibraries) {
15949 // Let's used the parsed package as scanResult.pkgSetting may be null
15950 final ParsedPackage parsedPackage = scanResult.request.parsedPackage;
15951 if (scanResult.staticSharedLibraryInfo == null
15952 && scanResult.dynamicSharedLibraryInfos == null) {
15956 // Any app can add new static shared libraries
15957 if (scanResult.staticSharedLibraryInfo != null) {
15958 return Collections.singletonList(scanResult.staticSharedLibraryInfo);
15960 final boolean hasDynamicLibraries = parsedPackage.isSystem()
15961 && scanResult.dynamicSharedLibraryInfos != null;
15962 if (!hasDynamicLibraries) {
15965 final boolean isUpdatedSystemApp = scanResult.pkgSetting.getPkgState()
15966 .isUpdatedSystemApp();
15967 // We may not yet have disabled the updated package yet, so be sure to grab the
15968 // current setting if that's the case.
15969 final PackageSetting updatedSystemPs = isUpdatedSystemApp
15970 ? scanResult.request.disabledPkgSetting == null
15971 ? scanResult.request.oldPkgSetting
15972 : scanResult.request.disabledPkgSetting
15974 if (isUpdatedSystemApp && (updatedSystemPs.pkg == null
15975 || updatedSystemPs.pkg.getLibraryNames() == null)) {
15976 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
15977 + " declares libraries that are not declared on the system image; skipping");
15980 final ArrayList<SharedLibraryInfo> infos =
15981 new ArrayList<>(scanResult.dynamicSharedLibraryInfos.size());
15982 for (SharedLibraryInfo info : scanResult.dynamicSharedLibraryInfos) {
15983 final String name = info.getName();
15984 if (isUpdatedSystemApp) {
15985 // New library entries can only be added through the
15986 // system image. This is important to get rid of a lot
15987 // of nasty edge cases: for example if we allowed a non-
15988 // system update of the app to add a library, then uninstalling
15989 // the update would make the library go away, and assumptions
15990 // we made such as through app install filtering would now
15991 // have allowed apps on the device which aren't compatible
15992 // with it. Better to just have the restriction here, be
15993 // conservative, and create many fewer cases that can negatively
15994 // impact the user experience.
15995 if (!updatedSystemPs.pkg.getLibraryNames().contains(name)) {
15996 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
15997 + " declares library " + name
15998 + " that is not declared on system image; skipping");
16002 if (sharedLibExists(
16003 name, SharedLibraryInfo.VERSION_UNDEFINED, existingSharedLibraries)) {
16004 Slog.w(TAG, "Package " + parsedPackage.getPackageName() + " declares library "
16005 + name + " that already exists; skipping");
16014 * Returns false if the adding shared library already exists in the map and so could not be
16017 private static boolean addSharedLibraryToPackageVersionMap(
16018 Map<String, LongSparseArray<SharedLibraryInfo>> target,
16019 SharedLibraryInfo library) {
16020 final String name = library.getName();
16021 if (target.containsKey(name)) {
16022 if (library.getType() != SharedLibraryInfo.TYPE_STATIC) {
16023 // We've already added this non-version-specific library to the map.
16025 } else if (target.get(name).indexOfKey(library.getLongVersion()) >= 0) {
16026 // We've already added this version of a version-specific library to the map.
16030 target.put(name, new LongSparseArray<>());
16032 target.get(name).put(library.getLongVersion(), library);
16036 @GuardedBy("mLock")
16037 private void commitPackagesLocked(final CommitRequest request) {
16038 // TODO: remove any expected failures from this method; this should only be able to fail due
16039 // to unavoidable errors (I/O, etc.)
16040 for (ReconciledPackage reconciledPkg : request.reconciledPackages.values()) {
16041 final ScanResult scanResult = reconciledPkg.scanResult;
16042 final ScanRequest scanRequest = scanResult.request;
16043 final ParsedPackage parsedPackage = scanRequest.parsedPackage;
16044 final String packageName = parsedPackage.getPackageName();
16045 final PackageInstalledInfo res = reconciledPkg.installResult;
16047 if (reconciledPkg.prepareResult.replace) {
16048 AndroidPackage oldPackage = mPackages.get(packageName);
16050 // Set the update and install times
16051 PackageSetting deletedPkgSetting = getPackageSetting(oldPackage.getPackageName());
16052 reconciledPkg.pkgSetting.firstInstallTime = deletedPkgSetting.firstInstallTime;
16053 reconciledPkg.pkgSetting.lastUpdateTime = System.currentTimeMillis();
16055 if (reconciledPkg.prepareResult.system) {
16056 // Remove existing system package
16057 removePackageLI(oldPackage, true);
16058 if (!disableSystemPackageLPw(oldPackage)) {
16059 // We didn't need to disable the .apk as a current system package,
16060 // which means we are replacing another update that is already
16061 // installed. We need to make sure to delete the older one's .apk.
16062 res.removedInfo.args = createInstallArgsForExisting(
16063 oldPackage.getCodePath(),
16064 oldPackage.getCodePath(),
16065 getAppDexInstructionSets(
16066 AndroidPackageUtils.getPrimaryCpuAbi(oldPackage,
16067 deletedPkgSetting),
16068 AndroidPackageUtils.getSecondaryCpuAbi(oldPackage,
16069 deletedPkgSetting)));
16071 res.removedInfo.args = null;
16075 // Settings will be written during the call to updateSettingsLI().
16076 executeDeletePackageLIF(reconciledPkg.deletePackageAction, packageName,
16077 true, request.mAllUsers, false, parsedPackage);
16078 } catch (SystemDeleteException e) {
16079 if (Build.IS_ENG) {
16080 throw new RuntimeException("Unexpected failure", e);
16081 // ignore; not possible for non-system app
16084 // Successfully deleted the old package; proceed with replace.
16086 // If deleted package lived in a container, give users a chance to
16087 // relinquish resources before killing.
16088 if (oldPackage.isExternalStorage()) {
16089 if (DEBUG_INSTALL) {
16090 Slog.i(TAG, "upgrading pkg " + oldPackage
16091 + " is ASEC-hosted -> UNAVAILABLE");
16093 final int[] uidArray = new int[]{oldPackage.getUid()};
16094 final ArrayList<String> pkgList = new ArrayList<>(1);
16095 pkgList.add(oldPackage.getPackageName());
16096 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16099 // Update the in-memory copy of the previous code paths.
16100 PackageSetting ps1 = mSettings.mPackages.get(
16101 reconciledPkg.prepareResult.existingPackage.getPackageName());
16102 if ((reconciledPkg.installArgs.installFlags & PackageManager.DONT_KILL_APP)
16104 if (ps1.mOldCodePaths == null) {
16105 ps1.mOldCodePaths = new ArraySet<>();
16107 Collections.addAll(ps1.mOldCodePaths, oldPackage.getBaseCodePath());
16108 if (oldPackage.getSplitCodePaths() != null) {
16109 Collections.addAll(ps1.mOldCodePaths, oldPackage.getSplitCodePaths());
16112 ps1.mOldCodePaths = null;
16115 if (reconciledPkg.installResult.returnCode
16116 == PackageManager.INSTALL_SUCCEEDED) {
16117 PackageSetting ps2 = mSettings.getPackageLPr(
16118 parsedPackage.getPackageName());
16120 res.removedInfo.removedForAllUsers = mPackages.get(ps2.name) == null;
16126 AndroidPackage pkg = commitReconciledScanResultLocked(reconciledPkg);
16127 updateSettingsLI(pkg, reconciledPkg.installArgs, request.mAllUsers, res);
16129 final PackageSetting ps = mSettings.mPackages.get(packageName);
16131 res.newUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
16132 ps.setUpdateAvailable(false /*updateAvailable*/);
16134 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16135 updateSequenceNumberLP(ps, res.newUsers);
16136 updateInstantAppInstallerLocked(packageName);
16142 * Installs one or more packages atomically. This operation is broken up into four phases:
16144 * <li><b>Prepare</b>
16145 * <br/>Analyzes any current install state, parses the package and does initial
16146 * validation on it.</li>
16148 * <br/>Interrogates the parsed packages given the context collected in prepare.</li>
16149 * <li><b>Reconcile</b>
16150 * <br/>Validates scanned packages in the context of each other and the current system
16151 * state to ensure that the install will be successful.
16152 * <li><b>Commit</b>
16153 * <br/>Commits all scanned packages and updates system state. This is the only place
16154 * that system state may be modified in the install flow and all predictable errors
16155 * must be determined before this phase.</li>
16158 * Failure at any phase will result in a full failure to install all packages.
16160 @GuardedBy("mInstallLock")
16161 private void installPackagesLI(List<InstallRequest> requests) {
16162 final Map<String, ScanResult> preparedScans = new ArrayMap<>(requests.size());
16163 final Map<String, InstallArgs> installArgs = new ArrayMap<>(requests.size());
16164 final Map<String, PackageInstalledInfo> installResults = new ArrayMap<>(requests.size());
16165 final Map<String, PrepareResult> prepareResults = new ArrayMap<>(requests.size());
16166 final Map<String, VersionInfo> versionInfos = new ArrayMap<>(requests.size());
16167 final Map<String, PackageSetting> lastStaticSharedLibSettings =
16168 new ArrayMap<>(requests.size());
16169 final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size());
16170 boolean success = false;
16172 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackagesLI");
16173 for (InstallRequest request : requests) {
16174 // TODO(b/109941548): remove this once we've pulled everything from it and into
16175 // scan, reconcile or commit.
16176 final PrepareResult prepareResult;
16178 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage");
16180 preparePackageLI(request.args, request.installResult);
16181 } catch (PrepareFailure prepareFailure) {
16182 request.installResult.setError(prepareFailure.error,
16183 prepareFailure.getMessage());
16184 request.installResult.origPackage = prepareFailure.conflictingPackage;
16185 request.installResult.origPermission = prepareFailure.conflictingPermission;
16188 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16190 request.installResult.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16191 request.installResult.installerPackageName =
16192 request.args.installSource.installerPackageName;
16194 final String packageName = prepareResult.packageToScan.getPackageName();
16195 prepareResults.put(packageName, prepareResult);
16196 installResults.put(packageName, request.installResult);
16197 installArgs.put(packageName, request.args);
16199 final ScanResult result = scanPackageTracedLI(
16200 prepareResult.packageToScan, prepareResult.parseFlags,
16201 prepareResult.scanFlags, System.currentTimeMillis(),
16202 request.args.user, request.args.abiOverride);
16203 if (null != preparedScans.put(result.pkgSetting.pkg.getPackageName(), result)) {
16204 request.installResult.setError(
16205 PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE,
16206 "Duplicate package " + result.pkgSetting.pkg.getPackageName()
16207 + " in multi-package install request.");
16210 createdAppId.put(packageName, optimisticallyRegisterAppId(result));
16211 versionInfos.put(result.pkgSetting.pkg.getPackageName(),
16212 getSettingsVersionForPackage(result.pkgSetting.pkg));
16213 if (result.staticSharedLibraryInfo != null) {
16214 final PackageSetting sharedLibLatestVersionSetting =
16215 getSharedLibLatestVersionSetting(result);
16216 if (sharedLibLatestVersionSetting != null) {
16217 lastStaticSharedLibSettings.put(result.pkgSetting.pkg.getPackageName(),
16218 sharedLibLatestVersionSetting);
16221 } catch (PackageManagerException e) {
16222 request.installResult.setError("Scanning Failed.", e);
16226 ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs,
16230 Collections.unmodifiableMap(mPackages), versionInfos,
16231 lastStaticSharedLibSettings);
16232 CommitRequest commitRequest = null;
16233 synchronized (mLock) {
16234 Map<String, ReconciledPackage> reconciledPackages;
16236 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages");
16237 reconciledPackages = reconcilePackagesLocked(
16238 reconcileRequest, mSettings.mKeySetManagerService);
16239 } catch (ReconcileFailure e) {
16240 for (InstallRequest request : requests) {
16241 request.installResult.setError("Reconciliation failed...", e);
16245 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16248 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "commitPackages");
16249 commitRequest = new CommitRequest(reconciledPackages,
16250 mUserManager.getUserIds());
16251 commitPackagesLocked(commitRequest);
16254 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16257 executePostCommitSteps(commitRequest);
16260 for (ScanResult result : preparedScans.values()) {
16261 if (createdAppId.getOrDefault(result.request.parsedPackage.getPackageName(),
16263 cleanUpAppIdCreation(result);
16266 // TODO(patb): create a more descriptive reason than unknown in future release
16267 // mark all non-failure installs as UNKNOWN so we do not treat them as success
16268 for (InstallRequest request : requests) {
16269 if (request.installResult.freezer != null) {
16270 request.installResult.freezer.close();
16272 if (request.installResult.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16273 request.installResult.returnCode = PackageManager.INSTALL_UNKNOWN;
16277 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16282 * On successful install, executes remaining steps after commit completes and the package lock
16283 * is released. These are typically more expensive or require calls to installd, which often
16284 * locks on {@link #mLock}.
16286 private void executePostCommitSteps(CommitRequest commitRequest) {
16287 for (ReconciledPackage reconciledPkg : commitRequest.reconciledPackages.values()) {
16288 final boolean instantApp = ((reconciledPkg.scanResult.request.scanFlags
16289 & PackageManagerService.SCAN_AS_INSTANT_APP) != 0);
16290 final AndroidPackage pkg = reconciledPkg.pkgSetting.pkg;
16291 final String packageName = pkg.getPackageName();
16292 final boolean onIncremental = mIncrementalManager != null
16293 && isIncrementalPath(pkg.getCodePath());
16294 prepareAppDataAfterInstallLIF(pkg);
16295 if (reconciledPkg.prepareResult.clearCodeCache) {
16296 clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
16297 | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16299 if (reconciledPkg.prepareResult.replace) {
16300 mDexManager.notifyPackageUpdated(pkg.getPackageName(),
16301 pkg.getBaseCodePath(), pkg.getSplitCodePaths());
16304 // Prepare the application profiles for the new code paths.
16305 // This needs to be done before invoking dexopt so that any install-time profile
16306 // can be used for optimizations.
16307 mArtManagerService.prepareAppProfiles(
16309 resolveUserIds(reconciledPkg.installArgs.user.getIdentifier()),
16310 /* updateReferenceProfileContent= */ true);
16312 // Check whether we need to dexopt the app.
16314 // NOTE: it is IMPORTANT to call dexopt:
16315 // - after doRename which will sync the package data from AndroidPackage and
16316 // its corresponding ApplicationInfo.
16317 // - after installNewPackageLIF or replacePackageLIF which will update result with the
16318 // uid of the application (pkg.applicationInfo.uid).
16319 // This update happens in place!
16321 // We only need to dexopt if the package meets ALL of the following conditions:
16322 // 1) it is not an instant app or if it is then dexopt is enabled via gservices.
16323 // 2) it is not debuggable.
16324 // 3) it is not on Incremental File System.
16326 // Note that we do not dexopt instant apps by default. dexopt can take some time to
16327 // complete, so we skip this step during installation. Instead, we'll take extra time
16328 // the first time the instant app starts. It's preferred to do it this way to provide
16329 // continuous progress to the useur instead of mysteriously blocking somewhere in the
16330 // middle of running an instant app. The default behaviour can be overridden
16332 final boolean performDexopt =
16333 (!instantApp || Global.getInt(mContext.getContentResolver(),
16334 Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
16335 && !pkg.isDebuggable()
16336 && (!onIncremental);
16338 if (performDexopt) {
16339 // Compile the layout resources.
16340 if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
16341 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "compileLayouts");
16342 mViewCompiler.compileLayouts(pkg);
16343 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16346 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
16347 // Do not run PackageDexOptimizer through the local performDexOpt
16348 // method because `pkg` may not be in `mPackages` yet.
16350 // Also, don't fail application installs if the dexopt step fails.
16351 DexoptOptions dexoptOptions = new DexoptOptions(packageName,
16353 DexoptOptions.DEXOPT_BOOT_COMPLETE
16354 | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE);
16355 ScanResult result = reconciledPkg.scanResult;
16357 // This mirrors logic from commitReconciledScanResultLocked, where the library files
16358 // needed for dexopt are assigned.
16359 // TODO: Fix this to have 1 mutable PackageSetting for scan/install. If the previous
16360 // setting needs to be passed to have a comparison, hide it behind an immutable
16361 // interface. There's no good reason to have 3 different ways to access the real
16362 // PackageSetting object, only one of which is actually correct.
16363 PackageSetting realPkgSetting = result.existingSettingCopied
16364 ? result.request.pkgSetting : result.pkgSetting;
16365 if (realPkgSetting == null) {
16366 realPkgSetting = reconciledPkg.pkgSetting;
16369 // Unfortunately, the updated system app flag is only tracked on this PackageSetting
16370 boolean isUpdatedSystemApp = reconciledPkg.pkgSetting.getPkgState()
16371 .isUpdatedSystemApp();
16373 realPkgSetting.getPkgState().setUpdatedSystemApp(isUpdatedSystemApp);
16375 mPackageDexOptimizer.performDexOpt(pkg, realPkgSetting,
16376 null /* instructionSets */,
16377 getOrCreateCompilerPackageStats(pkg),
16378 mDexManager.getPackageUseInfoOrDefault(packageName),
16380 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16383 // Notify BackgroundDexOptService that the package has been changed.
16384 // If this is an update of a package which used to fail to compile,
16385 // BackgroundDexOptService will remove it from its blacklist.
16386 // TODO: Layering violation
16387 BackgroundDexOptService.notifyPackageChanged(packageName);
16392 * The set of data needed to successfully install the prepared package. This includes data that
16393 * will be used to scan and reconcile the package.
16395 private static class PrepareResult {
16396 public final boolean replace;
16397 public final int scanFlags;
16398 public final int parseFlags;
16399 @Nullable /* The original Package if it is being replaced, otherwise {@code null} */
16400 public final AndroidPackage existingPackage;
16401 public final ParsedPackage packageToScan;
16402 public final boolean clearCodeCache;
16403 public final boolean system;
16404 public final PackageSetting originalPs;
16405 public final PackageSetting disabledPs;
16407 private PrepareResult(boolean replace, int scanFlags,
16408 int parseFlags, AndroidPackage existingPackage,
16409 ParsedPackage packageToScan, boolean clearCodeCache, boolean system,
16410 PackageSetting originalPs, PackageSetting disabledPs) {
16411 this.replace = replace;
16412 this.scanFlags = scanFlags;
16413 this.parseFlags = parseFlags;
16414 this.existingPackage = existingPackage;
16415 this.packageToScan = packageToScan;
16416 this.clearCodeCache = clearCodeCache;
16417 this.system = system;
16418 this.originalPs = originalPs;
16419 this.disabledPs = disabledPs;
16423 private static class PrepareFailure extends PackageManagerException {
16425 public String conflictingPackage;
16426 public String conflictingPermission;
16428 PrepareFailure(int error) {
16429 super(error, "Failed to prepare for install.");
16432 PrepareFailure(int error, String detailMessage) {
16433 super(error, detailMessage);
16436 PrepareFailure(String message, Exception e) {
16437 super(e instanceof PackageParserException
16438 ? ((PackageParserException) e).error
16439 : ((PackageManagerException) e).error,
16440 ExceptionUtils.getCompleteMessage(message, e));
16443 PrepareFailure conflictsWithExistingPermission(String conflictingPermission,
16444 String conflictingPackage) {
16445 this.conflictingPermission = conflictingPermission;
16446 this.conflictingPackage = conflictingPackage;
16451 @GuardedBy("mInstallLock")
16452 private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res)
16453 throws PrepareFailure {
16454 final int installFlags = args.installFlags;
16455 final File tmpPackageFile = new File(args.getCodePath());
16456 final boolean onExternal = args.volumeUuid != null;
16457 final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
16458 final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
16459 final boolean virtualPreload =
16460 ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
16461 @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
16462 if (args.move != null) {
16463 // moving a complete application; perform an initial scan on the new install location
16464 scanFlags |= SCAN_INITIAL;
16466 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
16467 scanFlags |= SCAN_DONT_KILL_APP;
16470 scanFlags |= SCAN_AS_INSTANT_APP;
16473 scanFlags |= SCAN_AS_FULL_APP;
16475 if (virtualPreload) {
16476 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
16479 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
16482 if (instantApp && onExternal) {
16483 Slog.i(TAG, "Incompatible ephemeral install; external=" + onExternal);
16484 throw new PrepareFailure(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16487 // Retrieve PackageSettings and parse package
16488 @ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
16489 | PackageParser.PARSE_ENFORCE_CODE
16490 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16492 PackageParser2 pp = new PackageParser2(mSeparateProcesses, false, mMetrics, null,
16493 mPackageParserCallback);
16495 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
16496 ParsedPackage parsedPackage;
16498 parsedPackage = pp.parsePackage(tmpPackageFile, parseFlags, false);
16499 AndroidPackageUtils.validatePackageDexMetadata(parsedPackage);
16500 } catch (PackageParserException e) {
16501 throw new PrepareFailure("Failed parse during installPackageLI", e);
16503 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16506 // Instant apps have several additional install-time checks.
16508 if (parsedPackage.getTargetSdkVersion() < Build.VERSION_CODES.O) {
16509 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
16510 + " does not target at least O");
16511 throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
16512 "Instant app package must target at least O");
16514 if (parsedPackage.getSharedUserId() != null) {
16515 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
16516 + " may not declare sharedUserId.");
16517 throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
16518 "Instant app package may not declare a sharedUserId");
16522 if (parsedPackage.isStaticSharedLibrary()) {
16523 // Static shared libraries have synthetic package names
16524 renameStaticSharedLibraryPackage(parsedPackage);
16526 // No static shared libs on external storage
16528 Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
16529 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16530 "Packages declaring static-shared libs cannot be updated");
16534 String pkgName = res.name = parsedPackage.getPackageName();
16535 if (parsedPackage.isTestOnly()) {
16536 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
16537 throw new PrepareFailure(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
16542 // either use what we've been given or parse directly from the APK
16543 if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
16544 parsedPackage.setSigningDetails(args.signingDetails);
16546 // TODO(b/136132412): skip for Incremental installation
16547 parsedPackage.setSigningDetails(
16548 ParsingPackageUtils.collectCertificates(parsedPackage, false /* skipVerify */));
16550 } catch (PackageParserException e) {
16551 throw new PrepareFailure("Failed collect during installPackageLI", e);
16554 if (instantApp && parsedPackage.getSigningDetails().signatureSchemeVersion
16555 < SignatureSchemeVersion.SIGNING_BLOCK_V2) {
16556 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
16557 + " is not signed with at least APK Signature Scheme v2");
16558 throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
16559 "Instant app package must be signed with APK Signature Scheme v2 or greater");
16562 // Get rid of all references to package scan path via parser.
16564 boolean systemApp = false;
16565 boolean replace = false;
16566 synchronized (mLock) {
16567 // Check if installing already existing package
16568 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16569 String oldName = mSettings.getRenamedPackageLPr(pkgName);
16570 if (parsedPackage.getOriginalPackages().contains(oldName)
16571 && mPackages.containsKey(oldName)) {
16572 // This package is derived from an original package,
16573 // and this device has been updating from that original
16574 // name. We must continue using the original name, so
16575 // rename the new package here.
16576 parsedPackage.setPackageName(oldName);
16577 pkgName = parsedPackage.getPackageName();
16579 if (DEBUG_INSTALL) {
16580 Slog.d(TAG, "Replacing existing renamed package: oldName="
16581 + oldName + " pkgName=" + pkgName);
16583 } else if (mPackages.containsKey(pkgName)) {
16584 // This package, under its official name, already exists
16585 // on the device; we should replace it.
16587 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
16591 // Prevent apps opting out from runtime permissions
16592 AndroidPackage oldPackage = mPackages.get(pkgName);
16593 final int oldTargetSdk = oldPackage.getTargetSdkVersion();
16594 final int newTargetSdk = parsedPackage.getTargetSdkVersion();
16595 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
16596 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
16597 throw new PrepareFailure(
16598 PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
16599 "Package " + parsedPackage.getPackageName()
16600 + " new target SDK " + newTargetSdk
16601 + " doesn't support runtime permissions but the old"
16602 + " target SDK " + oldTargetSdk + " does.");
16604 // Prevent persistent apps from being updated
16605 if (oldPackage.isPersistent()
16606 && ((installFlags & PackageManager.INSTALL_STAGED) == 0)) {
16607 throw new PrepareFailure(PackageManager.INSTALL_FAILED_INVALID_APK,
16608 "Package " + oldPackage.getPackageName() + " is a persistent app. "
16609 + "Persistent apps are not updateable.");
16614 PackageSetting ps = mSettings.mPackages.get(pkgName);
16616 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
16618 // Static shared libs have same package with different versions where
16619 // we internally use a synthetic package name to allow multiple versions
16620 // of the same package, therefore we need to compare signatures against
16621 // the package setting for the latest library version.
16622 PackageSetting signatureCheckPs = ps;
16623 if (parsedPackage.isStaticSharedLibrary()) {
16624 SharedLibraryInfo libraryInfo = getLatestSharedLibraVersionLPr(parsedPackage);
16625 if (libraryInfo != null) {
16626 signatureCheckPs = mSettings.getPackageLPr(libraryInfo.getPackageName());
16630 // Quick sanity check that we're signed correctly if updating;
16631 // we'll check this again later when scanning, but we want to
16632 // bail early here before tripping over redefined permissions.
16633 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16634 if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
16635 if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
16636 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
16637 + parsedPackage.getPackageName() + " upgrade keys do not match the "
16638 + "previously installed version");
16642 final boolean compareCompat = isCompatSignatureUpdateNeeded(parsedPackage);
16643 final boolean compareRecover = isRecoverSignatureUpdateNeeded(
16645 // We don't care about disabledPkgSetting on install for now.
16646 final boolean compatMatch = verifySignatures(signatureCheckPs, null,
16647 parsedPackage.getSigningDetails(), compareCompat, compareRecover);
16648 // The new KeySets will be re-added later in the scanning process.
16650 synchronized (mLock) {
16651 ksms.removeAppKeySetDataLPw(parsedPackage.getPackageName());
16654 } catch (PackageManagerException e) {
16655 throw new PrepareFailure(e.error, e.getMessage());
16659 if (ps.pkg != null) {
16660 systemApp = ps.pkg.isSystem();
16662 res.origUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
16666 int N = ArrayUtils.size(parsedPackage.getPermissions());
16667 for (int i = N - 1; i >= 0; i--) {
16668 final ParsedPermission perm = parsedPackage.getPermissions().get(i);
16669 final BasePermission bp = mPermissionManager.getPermissionTEMP(perm.getName());
16671 // Don't allow anyone but the system to define ephemeral permissions.
16672 if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
16674 Slog.w(TAG, "Non-System package " + parsedPackage.getPackageName()
16675 + " attempting to delcare ephemeral permission "
16676 + perm.getName() + "; Removing ephemeral.");
16677 perm.setProtectionLevel(perm.getProtectionLevel() & ~PermissionInfo.PROTECTION_FLAG_INSTANT);
16680 // Check whether the newly-scanned package wants to define an already-defined perm
16682 // If the defining package is signed with our cert, it's okay. This
16683 // also includes the "updating the same package" case, of course.
16684 // "updating same package" could also involve key-rotation.
16685 final boolean sigsOk;
16686 final String sourcePackageName = bp.getSourcePackageName();
16687 final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
16688 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16689 if (sourcePackageName.equals(parsedPackage.getPackageName())
16690 && (ksms.shouldCheckUpgradeKeySetLocked(
16691 sourcePackageSetting, scanFlags))) {
16692 sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, parsedPackage);
16695 // in the event of signing certificate rotation, we need to see if the
16696 // package's certificate has rotated from the current one, or if it is an
16697 // older certificate with which the current is ok with sharing permissions
16698 if (sourcePackageSetting.signatures.mSigningDetails.checkCapability(
16699 parsedPackage.getSigningDetails(),
16700 PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
16702 } else if (parsedPackage.getSigningDetails().checkCapability(
16703 sourcePackageSetting.signatures.mSigningDetails,
16704 PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
16706 // the scanned package checks out, has signing certificate rotation
16707 // history, and is newer; bring it over
16708 sourcePackageSetting.signatures.mSigningDetails =
16709 parsedPackage.getSigningDetails();
16716 // If the owning package is the system itself, we log but allow
16717 // install to proceed; we fail the install on all other permission
16719 if (!sourcePackageName.equals("android")) {
16720 throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
16721 + parsedPackage.getPackageName()
16722 + " attempting to redeclare permission "
16723 + perm.getName() + " already owned by "
16724 + sourcePackageName)
16725 .conflictsWithExistingPermission(perm.getName(),
16726 sourcePackageName);
16728 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
16729 + " attempting to redeclare system permission "
16730 + perm.getName() + "; ignoring new declaration");
16731 parsedPackage.removePermission(i);
16733 } else if (!PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())) {
16734 // Prevent apps to change protection level to dangerous from any other
16735 // type as this would allow a privilege escalation where an app adds a
16736 // normal/signature permission in other app's group and later redefines
16737 // it as dangerous leading to the group auto-grant.
16738 if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_MASK_BASE)
16739 == PermissionInfo.PROTECTION_DANGEROUS) {
16740 if (bp != null && !bp.isRuntime()) {
16741 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
16742 + " trying to change a non-runtime permission "
16744 + " to runtime; keeping old protection level");
16745 perm.setProtectionLevel(bp.getProtectionLevel());
16755 // Abort update; system app can't be replaced with app on sdcard
16756 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16757 "Cannot install updates to system apps on sdcard");
16758 } else if (instantApp) {
16759 // Abort update; system app can't be replaced with an instant app
16760 throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
16761 "Cannot update a system app with an instant app");
16765 if (args.move != null) {
16766 // We did an in-place move, so dex is ready to roll
16767 scanFlags |= SCAN_NO_DEX;
16768 scanFlags |= SCAN_MOVE;
16770 synchronized (mLock) {
16771 final PackageSetting ps = mSettings.mPackages.get(pkgName);
16773 res.setError(INSTALL_FAILED_INTERNAL_ERROR,
16774 "Missing settings for moved package " + pkgName);
16777 // We moved the entire application as-is, so bring over the
16778 // previously derived ABI information.
16779 parsedPackage.setPrimaryCpuAbi(ps.primaryCpuAbiString)
16780 .setSecondaryCpuAbi(ps.secondaryCpuAbiString);
16784 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
16785 scanFlags |= SCAN_NO_DEX;
16788 final boolean extractNativeLibs = !AndroidPackageUtils.isLibrary(parsedPackage);
16789 PackageSetting pkgSetting;
16790 synchronized (mLock) {
16791 pkgSetting = mSettings.getPackageLPr(pkgName);
16793 String abiOverride =
16794 (pkgSetting == null || TextUtils.isEmpty(pkgSetting.cpuAbiOverrideString)
16795 ? args.abiOverride : pkgSetting.cpuAbiOverrideString);
16796 boolean isUpdatedSystemAppFromExistingSetting = pkgSetting != null
16797 && pkgSetting.getPkgState().isUpdatedSystemApp();
16798 AndroidPackage oldPackage = mPackages.get(pkgName);
16799 boolean isUpdatedSystemAppInferred = oldPackage != null && oldPackage.isSystem();
16800 final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
16801 derivedAbi = mInjector.getAbiHelper().derivePackageAbi(parsedPackage,
16802 isUpdatedSystemAppFromExistingSetting || isUpdatedSystemAppInferred,
16803 abiOverride, extractNativeLibs);
16804 derivedAbi.first.applyTo(parsedPackage);
16805 derivedAbi.second.applyTo(parsedPackage);
16806 } catch (PackageManagerException pme) {
16807 Slog.e(TAG, "Error deriving application ABI", pme);
16808 throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
16809 "Error deriving application ABI");
16813 if (!args.doRename(res.returnCode, parsedPackage)) {
16814 throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
16818 setUpFsVerityIfPossible(parsedPackage);
16819 } catch (InstallerException | IOException | DigestException | NoSuchAlgorithmException e) {
16820 throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
16821 "Failed to set up verity: " + e);
16825 startIntentFilterVerifications(args.user.getIdentifier(), replace, parsedPackage);
16827 if (DEBUG_DOMAIN_VERIFICATION) {
16828 Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);
16831 final PackageFreezer freezer =
16832 freezePackageForInstall(pkgName, installFlags, "installPackageLI");
16833 boolean shouldCloseFreezerBeforeReturn = true;
16835 final AndroidPackage existingPackage;
16836 String renamedPackage = null;
16837 boolean sysPkg = false;
16838 int targetScanFlags = scanFlags;
16839 int targetParseFlags = parseFlags;
16840 final PackageSetting ps;
16841 final PackageSetting disabledPs;
16842 final PackageSetting[] childPackages;
16844 if (parsedPackage.isStaticSharedLibrary()) {
16845 // Static libs have a synthetic package name containing the version
16846 // and cannot be updated as an update would get a new package name,
16847 // unless this is the exact same version code which is useful for
16849 AndroidPackage existingPkg = mPackages.get(parsedPackage.getPackageName());
16850 if (existingPkg != null
16851 && existingPkg.getLongVersionCode()
16852 != parsedPackage.getLongVersionCode()) {
16853 throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PACKAGE,
16854 "Packages declaring "
16855 + "static-shared libs cannot be updated");
16859 final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16861 final AndroidPackage oldPackage;
16862 final String pkgName11 = parsedPackage.getPackageName();
16863 final int[] allUsers;
16864 final int[] installedUsers;
16866 synchronized (mLock) {
16867 oldPackage = mPackages.get(pkgName11);
16868 existingPackage = oldPackage;
16869 if (DEBUG_INSTALL) {
16870 // TODO(b/135203078): PackageImpl.toString()
16872 "replacePackageLI: new=" + parsedPackage + ", old=" + oldPackage);
16875 ps = mSettings.mPackages.get(pkgName11);
16876 disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
16878 // verify signatures are valid
16879 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16880 if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
16881 if (!ksms.checkUpgradeKeySetLocked(ps, parsedPackage)) {
16882 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16883 "New package not signed by keys specified by upgrade-keysets: "
16887 // default to original signature matching
16888 if (!parsedPackage.getSigningDetails().checkCapability(
16889 oldPackage.getSigningDetails(),
16890 SigningDetails.CertCapabilities.INSTALLED_DATA)
16891 && !oldPackage.getSigningDetails().checkCapability(
16892 parsedPackage.getSigningDetails(),
16893 SigningDetails.CertCapabilities.ROLLBACK)) {
16894 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16895 "New package has a different signature: " + pkgName11);
16899 // don't allow a system upgrade unless the upgrade hash matches
16900 if (oldPackage.getRestrictUpdateHash() != null && oldPackage.isSystem()) {
16901 final byte[] digestBytes;
16903 final MessageDigest digest = MessageDigest.getInstance("SHA-512");
16904 updateDigest(digest, new File(parsedPackage.getBaseCodePath()));
16905 if (!ArrayUtils.isEmpty(parsedPackage.getSplitCodePaths())) {
16906 for (String path : parsedPackage.getSplitCodePaths()) {
16907 updateDigest(digest, new File(path));
16910 digestBytes = digest.digest();
16911 } catch (NoSuchAlgorithmException | IOException e) {
16912 throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
16913 "Could not compute hash: " + pkgName11);
16915 if (!Arrays.equals(oldPackage.getRestrictUpdateHash(), digestBytes)) {
16916 throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
16917 "New package fails restrict-update check: " + pkgName11);
16919 // retain upgrade restriction
16920 parsedPackage.setRestrictUpdateHash(oldPackage.getRestrictUpdateHash());
16923 // Check for shared user id changes
16924 String invalidPackageName = null;
16925 if (!Objects.equals(oldPackage.getSharedUserId(),
16926 parsedPackage.getSharedUserId())) {
16927 invalidPackageName = parsedPackage.getPackageName();
16930 if (invalidPackageName != null) {
16931 throw new PrepareFailure(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
16932 "Package " + invalidPackageName + " tried to change user "
16933 + oldPackage.getSharedUserId());
16936 // In case of rollback, remember per-user/profile install state
16937 allUsers = mUserManager.getUserIds();
16938 installedUsers = ps.queryInstalledUsers(allUsers, true);
16941 // don't allow an upgrade from full to ephemeral
16942 if (isInstantApp) {
16943 if (args.user == null || args.user.getIdentifier() == UserHandle.USER_ALL) {
16944 for (int currentUser : allUsers) {
16945 if (!ps.getInstantApp(currentUser)) {
16946 // can't downgrade from full to instant
16948 "Can't replace full app with instant app: " + pkgName11
16949 + " for user: " + currentUser);
16950 throw new PrepareFailure(
16951 PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16954 } else if (!ps.getInstantApp(args.user.getIdentifier())) {
16955 // can't downgrade from full to instant
16956 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName11
16957 + " for user: " + args.user.getIdentifier());
16958 throw new PrepareFailure(
16959 PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16964 // Update what is removed
16965 res.removedInfo = new PackageRemovedInfo(this);
16966 res.removedInfo.uid = oldPackage.getUid();
16967 res.removedInfo.removedPackage = oldPackage.getPackageName();
16968 res.removedInfo.installerPackageName = ps.installSource.installerPackageName;
16969 res.removedInfo.isStaticSharedLib = parsedPackage.getStaticSharedLibName() != null;
16970 res.removedInfo.isUpdate = true;
16971 res.removedInfo.origUsers = installedUsers;
16972 res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
16973 for (int i = 0; i < installedUsers.length; i++) {
16974 final int userId = installedUsers[i];
16975 res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
16978 sysPkg = oldPackage.isSystem();
16980 // Set the system/privileged/oem/vendor/product flags as needed
16981 final boolean privileged = oldPackage.isPrivileged();
16982 final boolean oem = oldPackage.isOem();
16983 final boolean vendor = oldPackage.isVendor();
16984 final boolean product = oldPackage.isProduct();
16985 final boolean odm = oldPackage.isOdm();
16986 final boolean systemExt = oldPackage.isSystemExt();
16987 final @ParseFlags int systemParseFlags = parseFlags;
16988 final @ScanFlags int systemScanFlags = scanFlags
16990 | (privileged ? SCAN_AS_PRIVILEGED : 0)
16991 | (oem ? SCAN_AS_OEM : 0)
16992 | (vendor ? SCAN_AS_VENDOR : 0)
16993 | (product ? SCAN_AS_PRODUCT : 0)
16994 | (odm ? SCAN_AS_ODM : 0)
16995 | (systemExt ? SCAN_AS_SYSTEM_EXT : 0);
16997 if (DEBUG_INSTALL) {
16998 Slog.d(TAG, "replaceSystemPackageLI: new=" + parsedPackage
16999 + ", old=" + oldPackage);
17001 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17002 targetParseFlags = systemParseFlags;
17003 targetScanFlags = systemScanFlags;
17004 } else { // non system replace
17006 if (DEBUG_INSTALL) {
17008 "replaceNonSystemPackageLI: new=" + parsedPackage + ", old="
17012 } else { // new package install
17016 existingPackage = null;
17017 // Remember this for later, in case we need to rollback this install
17018 String pkgName1 = parsedPackage.getPackageName();
17020 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + parsedPackage);
17022 // TODO(patb): MOVE TO RECONCILE
17023 synchronized (mLock) {
17024 renamedPackage = mSettings.getRenamedPackageLPr(pkgName1);
17025 if (renamedPackage != null) {
17026 // A package with the same name is already installed, though
17027 // it has been renamed to an older name. The package we
17028 // are trying to install should be installed as an update to
17029 // the existing one, but that has not been requested, so bail.
17030 throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS,
17031 "Attempt to re-install " + pkgName1
17032 + " without first uninstalling package running as "
17035 if (mPackages.containsKey(pkgName1)) {
17036 // Don't allow installation over an existing package with the same name.
17037 throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS,
17038 "Attempt to re-install " + pkgName1
17039 + " without first uninstalling.");
17043 // we're passing the freezer back to be closed in a later phase of install
17044 shouldCloseFreezerBeforeReturn = false;
17046 return new PrepareResult(replace, targetScanFlags, targetParseFlags,
17047 existingPackage, parsedPackage, replace /* clearCodeCache */, sysPkg,
17050 res.freezer = freezer;
17051 if (shouldCloseFreezerBeforeReturn) {
17058 * Set up fs-verity for the given package if possible. This requires a feature flag of system
17059 * property to be enabled only if the kernel supports fs-verity.
17061 * <p>When the feature flag is set to legacy mode, only APK is supported (with some experimental
17062 * kernel patches). In normal mode, all file format can be supported.
17064 private void setUpFsVerityIfPossible(AndroidPackage pkg) throws InstallerException,
17065 PrepareFailure, IOException, DigestException, NoSuchAlgorithmException {
17066 final boolean standardMode = PackageManagerServiceUtils.isApkVerityEnabled();
17067 final boolean legacyMode = PackageManagerServiceUtils.isLegacyApkVerityEnabled();
17068 if (!standardMode && !legacyMode) {
17072 // Collect files we care for fs-verity setup.
17073 ArrayMap<String, String> fsverityCandidates = new ArrayMap<>();
17075 synchronized (mLock) {
17076 final PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
17077 if (ps != null && ps.isPrivileged()) {
17078 fsverityCandidates.put(pkg.getBaseCodePath(), null);
17079 if (pkg.getSplitCodePaths() != null) {
17080 for (String splitPath : pkg.getSplitCodePaths()) {
17081 fsverityCandidates.put(splitPath, null);
17087 // NB: These files will become only accessible if the signing key is loaded in kernel's
17088 // .fs-verity keyring.
17089 fsverityCandidates.put(pkg.getBaseCodePath(),
17090 VerityUtils.getFsveritySignatureFilePath(pkg.getBaseCodePath()));
17092 final String dmPath = DexMetadataHelper.buildDexMetadataPathForApk(
17093 pkg.getBaseCodePath());
17094 if (new File(dmPath).exists()) {
17095 fsverityCandidates.put(dmPath, VerityUtils.getFsveritySignatureFilePath(dmPath));
17098 if (pkg.getSplitCodePaths() != null) {
17099 for (String path : pkg.getSplitCodePaths()) {
17100 fsverityCandidates.put(path, VerityUtils.getFsveritySignatureFilePath(path));
17102 final String splitDmPath = DexMetadataHelper.buildDexMetadataPathForApk(path);
17103 if (new File(splitDmPath).exists()) {
17104 fsverityCandidates.put(splitDmPath,
17105 VerityUtils.getFsveritySignatureFilePath(splitDmPath));
17111 for (Map.Entry<String, String> entry : fsverityCandidates.entrySet()) {
17112 final String filePath = entry.getKey();
17113 final String signaturePath = entry.getValue();
17116 // fs-verity is optional for now. Only set up if signature is provided.
17117 if (new File(signaturePath).exists() && !VerityUtils.hasFsverity(filePath)) {
17119 VerityUtils.setUpFsverity(filePath, signaturePath);
17120 } catch (IOException e) {
17121 throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
17122 "Failed to enable fs-verity: " + e);
17128 // In legacy mode, fs-verity can only be enabled by process with CAP_SYS_ADMIN.
17129 final VerityUtils.SetupResult result = VerityUtils.generateApkVeritySetupData(filePath);
17130 if (result.isOk()) {
17131 if (Build.IS_DEBUGGABLE) Slog.i(TAG, "Enabling verity to " + filePath);
17132 final FileDescriptor fd = result.getUnownedFileDescriptor();
17134 final byte[] rootHash = VerityUtils.generateApkVerityRootHash(filePath);
17136 // A file may already have fs-verity, e.g. when reused during a split
17137 // install. If the measurement succeeds, no need to attempt to set up.
17138 mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
17139 } catch (InstallerException e) {
17140 mInstaller.installApkVerity(filePath, fd, result.getContentSize());
17141 mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
17144 IoUtils.closeQuietly(fd);
17146 } else if (result.isFailed()) {
17147 throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
17148 "Failed to generate verity");
17153 private void startIntentFilterVerifications(int userId, boolean replacing, AndroidPackage pkg) {
17154 if (mIntentFilterVerifierComponent == null) {
17155 Slog.w(TAG, "No IntentFilter verification will not be done as "
17156 + "there is no IntentFilterVerifier available!");
17160 final int verifierUid = getPackageUid(
17161 mIntentFilterVerifierComponent.getPackageName(),
17162 MATCH_DEBUG_TRIAGED_MISSING,
17163 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
17165 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17166 msg.obj = new IFVerificationParams(
17167 pkg.getPackageName(),
17168 pkg.isHasDomainUrls(),
17169 pkg.getActivities(),
17174 mHandler.sendMessage(msg);
17177 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
17178 String packageName,
17179 boolean hasDomainUrls,
17180 List<ParsedActivity> activities) {
17181 int size = activities.size();
17183 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17184 "No activity, so no need to verify any IntentFilter!");
17188 if (!hasDomainUrls) {
17189 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17190 "No domain URLs, so no need to verify any IntentFilter!");
17194 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
17195 + " if any IntentFilter from the " + size
17196 + " Activities needs verification ...");
17199 boolean handlesWebUris = false;
17200 final boolean alreadyVerified;
17201 synchronized (mLock) {
17202 // If this is a new install and we see that we've already run verification for this
17203 // package, we have nothing to do: it means the state was restored from backup.
17204 final IntentFilterVerificationInfo ivi =
17205 mSettings.getIntentFilterVerificationLPr(packageName);
17206 alreadyVerified = (ivi != null);
17207 if (!replacing && alreadyVerified) {
17208 if (DEBUG_DOMAIN_VERIFICATION) {
17209 Slog.i(TAG, "Package " + packageName + " already verified: status="
17210 + ivi.getStatusString());
17215 // If any filters need to be verified, then all need to be. In addition, we need to
17216 // know whether an updating app has any web navigation intent filters, to re-
17217 // examine handling policy even if not re-verifying.
17218 boolean needToVerify = false;
17219 for (ParsedActivity a : activities) {
17220 for (ParsedIntentInfo filter : a.getIntents()) {
17221 if (filter.handlesWebUris(true)) {
17222 handlesWebUris = true;
17224 if (filter.needsVerification()
17225 && needsNetworkVerificationLPr(a.getPackageName())) {
17226 if (DEBUG_DOMAIN_VERIFICATION) {
17228 "Intent filter needs verification, so processing all filters");
17230 needToVerify = true;
17231 // It's safe to break out here because filter.needsVerification()
17232 // can only be true if filter.handlesWebUris(true) returns true, so
17233 // we've already noted that.
17239 // Note whether this app publishes any web navigation handling support at all,
17240 // and whether there are any web-nav filters that fit the profile for running
17241 // a verification pass now.
17242 if (needToVerify) {
17243 final int verificationId = mIntentFilterVerificationToken++;
17244 for (ParsedActivity a : activities) {
17245 for (ParsedIntentInfo filter : a.getIntents()) {
17246 if (filter.handlesWebUris(true)
17247 && needsNetworkVerificationLPr(a.getPackageName())) {
17248 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17249 "Verification needed for IntentFilter:" + filter.toString());
17250 mIntentFilterVerifier.addOneIntentFilterVerification(
17251 verifierUid, userId, verificationId, filter, packageName);
17260 // count > 0 means that we're running a full verification pass
17261 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17262 + " IntentFilter verification" + (count > 1 ? "s" : "")
17263 + " for userId:" + userId);
17264 mIntentFilterVerifier.startVerifications(userId);
17265 } else if (alreadyVerified && handlesWebUris) {
17266 // App used autoVerify in the past, no longer does, but still handles web
17267 // navigation starts.
17268 if (DEBUG_DOMAIN_VERIFICATION) {
17269 Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy");
17271 synchronized (mLock) {
17272 clearIntentFilterVerificationsLPw(packageName, userId);
17275 if (DEBUG_DOMAIN_VERIFICATION) {
17276 Slog.d(TAG, "No web filters or no prior verify policy for " + packageName);
17281 @GuardedBy("mLock")
17282 private boolean needsNetworkVerificationLPr(String packageName) {
17283 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17288 int status = ivi.getStatus();
17290 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17291 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
17292 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17301 private static boolean isExternal(PackageSetting ps) {
17302 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17305 private static boolean isSystemApp(PackageSetting ps) {
17306 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17309 private static boolean isUpdatedSystemApp(PackageSetting ps) {
17310 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17313 private VersionInfo getSettingsVersionForPackage(AndroidPackage pkg) {
17314 if (pkg.isExternalStorage()) {
17315 if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
17316 return mSettings.getExternalVersion();
17318 return mSettings.findOrCreateVersion(pkg.getVolumeUuid());
17321 return mSettings.getInternalVersion();
17326 public void deletePackageAsUser(String packageName, int versionCode,
17327 IPackageDeleteObserver observer, int userId, int flags) {
17328 deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17329 new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17333 public void deletePackageVersioned(VersionedPackage versionedPackage,
17334 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17335 final int callingUid = Binder.getCallingUid();
17336 mContext.enforceCallingOrSelfPermission(
17337 android.Manifest.permission.DELETE_PACKAGES, null);
17338 final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
17339 Preconditions.checkNotNull(versionedPackage);
17340 Preconditions.checkNotNull(observer);
17341 Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
17342 PackageManager.VERSION_CODE_HIGHEST,
17343 Long.MAX_VALUE, "versionCode must be >= -1");
17345 final String packageName = versionedPackage.getPackageName();
17346 final long versionCode = versionedPackage.getLongVersionCode();
17347 final String internalPackageName;
17348 synchronized (mLock) {
17349 // Normalize package name to handle renamed packages and static libs
17350 internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
17353 final int uid = Binder.getCallingUid();
17354 if (!isOrphaned(internalPackageName)
17355 && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17356 mHandler.post(() -> {
17358 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17359 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17360 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17361 observer.onUserActionRequired(intent);
17362 } catch (RemoteException re) {
17367 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17368 final int[] users = deleteAllUsers ? mUserManager.getUserIds() : new int[]{userId};
17369 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17370 mContext.enforceCallingOrSelfPermission(
17371 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17372 "deletePackage for user " + userId);
17375 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17376 mHandler.post(() -> {
17378 observer.onPackageDeleted(packageName,
17379 PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17380 } catch (RemoteException re) {
17386 if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17387 mHandler.post(() -> {
17389 observer.onPackageDeleted(packageName,
17390 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17391 } catch (RemoteException re) {
17397 if (DEBUG_REMOVE) {
17398 Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17399 + " deleteAllUsers: " + deleteAllUsers + " version="
17400 + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17401 ? "VERSION_CODE_HIGHEST" : versionCode));
17403 // Queue up an async operation since the package deletion may take a little while.
17404 mHandler.post(() -> {
17406 final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
17407 boolean doDeletePackage = true;
17409 final boolean targetIsInstantApp =
17410 ps.getInstantApp(UserHandle.getUserId(callingUid));
17411 doDeletePackage = !targetIsInstantApp
17412 || canViewInstantApps;
17414 if (doDeletePackage) {
17415 if (!deleteAllUsers) {
17416 returnCode = deletePackageX(internalPackageName, versionCode,
17417 userId, deleteFlags);
17419 int[] blockUninstallUserIds = getBlockUninstallForUsers(
17420 internalPackageName, users);
17421 // If nobody is blocking uninstall, proceed with delete for all users
17422 if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17423 returnCode = deletePackageX(internalPackageName, versionCode,
17424 userId, deleteFlags);
17426 // Otherwise uninstall individually for users with blockUninstalls=false
17427 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17428 for (int userId1 : users) {
17429 if (!ArrayUtils.contains(blockUninstallUserIds, userId1)) {
17430 returnCode = deletePackageX(internalPackageName, versionCode,
17431 userId1, userFlags);
17432 if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17433 Slog.w(TAG, "Package delete failed for user " + userId1
17434 + ", returnCode " + returnCode);
17438 // The app has only been marked uninstalled for certain users.
17439 // We still need to report that delete was blocked
17440 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17444 returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17447 observer.onPackageDeleted(packageName, returnCode, null);
17448 } catch (RemoteException e) {
17449 Log.i(TAG, "Observer no longer exists.");
17454 private String resolveExternalPackageNameLPr(AndroidPackage pkg) {
17455 if (pkg.getStaticSharedLibName() != null) {
17456 return pkg.getManifestPackageName();
17458 return pkg.getPackageName();
17461 @GuardedBy("mLock")
17462 private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
17463 final int callingUid = Binder.getCallingUid();
17464 return resolveInternalPackageNameInternalLocked(packageName, versionCode,
17468 private String resolveInternalPackageNameInternalLocked(
17469 String packageName, long versionCode, int callingUid) {
17470 // Handle renamed packages
17471 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17472 packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17474 // Is this a static library?
17475 LongSparseArray<SharedLibraryInfo> versionedLib =
17476 mStaticLibsByDeclaringPackage.get(packageName);
17477 if (versionedLib == null || versionedLib.size() <= 0) {
17478 return packageName;
17481 // Figure out which lib versions the caller can see
17482 LongSparseLongArray versionsCallerCanSee = null;
17483 final int callingAppId = UserHandle.getAppId(callingUid);
17484 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17485 && callingAppId != Process.ROOT_UID) {
17486 versionsCallerCanSee = new LongSparseLongArray();
17487 String libName = versionedLib.valueAt(0).getName();
17488 String[] uidPackages = getPackagesForUidInternal(callingUid, callingUid);
17489 if (uidPackages != null) {
17490 for (String uidPackage : uidPackages) {
17491 PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17492 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17494 final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
17495 versionsCallerCanSee.append(libVersion, libVersion);
17501 // Caller can see nothing - done
17502 if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17503 return packageName;
17506 // Find the version the caller can see and the app version code
17507 SharedLibraryInfo highestVersion = null;
17508 final int versionCount = versionedLib.size();
17509 for (int i = 0; i < versionCount; i++) {
17510 SharedLibraryInfo libraryInfo = versionedLib.valueAt(i);
17511 if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17512 libraryInfo.getLongVersion()) < 0) {
17515 final long libVersionCode = libraryInfo.getDeclaringPackage().getLongVersionCode();
17516 if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17517 if (libVersionCode == versionCode) {
17518 return libraryInfo.getPackageName();
17520 } else if (highestVersion == null) {
17521 highestVersion = libraryInfo;
17522 } else if (libVersionCode > highestVersion
17523 .getDeclaringPackage().getLongVersionCode()) {
17524 highestVersion = libraryInfo;
17528 if (highestVersion != null) {
17529 return highestVersion.getPackageName();
17532 return packageName;
17535 boolean isCallerVerifier(int callingUid) {
17536 final int callingUserId = UserHandle.getUserId(callingUid);
17537 return mRequiredVerifierPackage != null &&
17538 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
17541 private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17542 if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17543 || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
17546 final int callingUserId = UserHandle.getUserId(callingUid);
17547 // If the caller installed the pkgName, then allow it to silently uninstall.
17548 if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
17552 // Allow package verifier to silently uninstall.
17553 if (mRequiredVerifierPackage != null &&
17554 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
17558 // Allow package uninstaller to silently uninstall.
17559 if (mRequiredUninstallerPackage != null &&
17560 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
17564 // Allow storage manager to silently uninstall.
17565 if (mStorageManagerPackage != null &&
17566 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
17570 // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
17571 // uninstall for device owner provisioning.
17572 if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
17573 == PERMISSION_GRANTED) {
17580 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
17581 int[] result = EMPTY_INT_ARRAY;
17582 for (int userId : userIds) {
17583 if (getBlockUninstallForUser(packageName, userId)) {
17584 result = ArrayUtils.appendInt(result, userId);
17591 public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
17592 final int callingUid = Binder.getCallingUid();
17593 if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
17594 != PERMISSION_GRANTED) {
17595 EventLog.writeEvent(0x534e4554, "128599183", -1, "");
17596 throw new SecurityException(android.Manifest.permission.MANAGE_USERS
17597 + " permission is required to call this API");
17599 if (getInstantAppPackageName(callingUid) != null
17600 && !isCallerSameApp(packageName, callingUid)) {
17603 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
17606 private boolean isPackageDeviceAdmin(String packageName, int userId) {
17607 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
17608 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
17611 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
17612 /* callingUserOnly =*/ false);
17613 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
17614 : deviceOwnerComponentName.getPackageName();
17615 // Does the package contains the device owner?
17616 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise,
17617 // this check is probably not needed, since DO should be registered as a device
17618 // admin on some user too. (Original bug for this: b/17657954)
17619 if (packageName.equals(deviceOwnerPackageName)) {
17622 // Does it contain a device admin for any user?
17624 if (userId == UserHandle.USER_ALL) {
17625 users = mUserManager.getUserIds();
17627 users = new int[]{userId};
17629 for (int i = 0; i < users.length; ++i) {
17630 if (dpm.packageHasActiveAdmins(packageName, users[i])) {
17635 } catch (RemoteException e) {
17640 private boolean shouldKeepUninstalledPackageLPr(String packageName) {
17641 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
17645 * This method is an internal method that could be get invoked either
17646 * to delete an installed package or to clean up a failed installation.
17647 * After deleting an installed package, a broadcast is sent to notify any
17648 * listeners that the package has been removed. For cleaning up a failed
17649 * installation, the broadcast is not necessary since the package's
17650 * installation wouldn't have sent the initial broadcast either
17651 * The key steps in deleting a package are
17652 * deleting the package information in internal structures like mPackages,
17653 * deleting the packages base directories through installd
17654 * updating mSettings to reflect current status
17655 * persisting settings for later use
17656 * sending a broadcast if necessary
17658 int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
17659 final PackageRemovedInfo info = new PackageRemovedInfo(this);
17662 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
17663 ? UserHandle.USER_ALL : userId;
17665 if (isPackageDeviceAdmin(packageName, removeUser)) {
17666 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
17667 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
17670 final PackageSetting uninstalledPs;
17671 final PackageSetting disabledSystemPs;
17672 final AndroidPackage pkg;
17674 // for the uninstall-updates case and restricted profiles, remember the per-
17675 // user handle installed state
17677 /** enabled state of the uninstalled application */
17678 final int origEnabledState;
17679 synchronized (mLock) {
17680 uninstalledPs = mSettings.mPackages.get(packageName);
17681 if (uninstalledPs == null) {
17682 Slog.w(TAG, "Not removing non-existent package " + packageName);
17683 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17686 if (versionCode != PackageManager.VERSION_CODE_HIGHEST
17687 && uninstalledPs.versionCode != versionCode) {
17688 Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
17689 + uninstalledPs.versionCode + " != " + versionCode);
17690 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17693 disabledSystemPs = mSettings.getDisabledSystemPkgLPr(packageName);
17694 // Save the enabled state before we delete the package. When deleting a stub
17695 // application we always set the enabled state to 'disabled'.
17696 origEnabledState = uninstalledPs == null
17697 ? COMPONENT_ENABLED_STATE_DEFAULT : uninstalledPs.getEnabled(userId);
17698 // Static shared libs can be declared by any package, so let us not
17699 // allow removing a package if it provides a lib others depend on.
17700 pkg = mPackages.get(packageName);
17702 allUsers = mUserManager.getUserIds();
17704 if (pkg != null && pkg.getStaticSharedLibName() != null) {
17705 SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(
17706 pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion());
17707 if (libraryInfo != null) {
17708 for (int currUserId : allUsers) {
17709 if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
17712 List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
17713 libraryInfo, MATCH_KNOWN_PACKAGES, currUserId);
17714 if (!ArrayUtils.isEmpty(libClientPackages)) {
17715 Slog.w(TAG, "Not removing package " + pkg.getManifestPackageName()
17716 + " hosting lib " + libraryInfo.getName() + " version "
17717 + libraryInfo.getLongVersion() + " used by " + libClientPackages
17718 + " for user " + currUserId);
17719 return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
17725 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
17728 final int freezeUser;
17729 if (isUpdatedSystemApp(uninstalledPs)
17730 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
17731 // We're downgrading a system app, which will apply to all users, so
17732 // freeze them all during the downgrade
17733 freezeUser = UserHandle.USER_ALL;
17735 freezeUser = removeUser;
17738 synchronized (mInstallLock) {
17739 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
17740 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
17741 deleteFlags, "deletePackageX")) {
17742 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
17743 deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
17745 synchronized (mLock) {
17748 mInstantAppRegistry.onPackageUninstalledLPw(pkg, uninstalledPs,
17749 info.removedUsers);
17751 updateSequenceNumberLP(uninstalledPs, info.removedUsers);
17752 updateInstantAppInstallerLocked(packageName);
17758 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
17759 info.sendPackageRemovedBroadcasts(killApp);
17760 info.sendSystemPackageUpdatedBroadcasts();
17761 info.sendSystemPackageAppearedBroadcasts();
17763 // Force a gc here.
17764 Runtime.getRuntime().gc();
17765 // Delete the resources here after sending the broadcast to let
17766 // other processes clean up before deleting resources.
17767 synchronized (mInstallLock) {
17768 if (info.args != null) {
17769 info.args.doPostDeleteLI(true);
17771 final AndroidPackage stubPkg =
17772 (disabledSystemPs == null) ? null : disabledSystemPs.pkg;
17773 if (stubPkg != null && stubPkg.isStub()) {
17774 final PackageSetting stubPs;
17775 synchronized (mLock) {
17776 // restore the enabled state of the stub; the state is overwritten when
17777 // the stub is uninstalled
17778 stubPs = mSettings.getPackageLPr(stubPkg.getPackageName());
17779 if (stubPs != null) {
17780 stubPs.setEnabled(origEnabledState, userId, "android");
17783 if (origEnabledState == COMPONENT_ENABLED_STATE_DEFAULT
17784 || origEnabledState == COMPONENT_ENABLED_STATE_ENABLED) {
17785 if (DEBUG_COMPRESSION) {
17786 Slog.i(TAG, "Enabling system stub after removal; pkg: "
17787 + stubPkg.getPackageName());
17789 enableCompressedPackage(stubPkg, stubPs);
17794 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17797 static class PackageRemovedInfo {
17798 final PackageSender packageSender;
17799 String removedPackage;
17800 String installerPackageName;
17802 int removedAppId = -1;
17804 int[] removedUsers = null;
17805 int[] broadcastUsers = null;
17806 int[] instantUserIds = null;
17807 SparseArray<Integer> installReasons;
17808 boolean isRemovedPackageSystemUpdate = false;
17810 boolean dataRemoved;
17811 boolean removedForAllUsers;
17812 boolean isStaticSharedLib;
17813 // Clean up resources deleted packages.
17814 InstallArgs args = null;
17815 ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
17817 PackageRemovedInfo(PackageSender packageSender) {
17818 this.packageSender = packageSender;
17821 void sendPackageRemovedBroadcasts(boolean killApp) {
17822 sendPackageRemovedBroadcastInternal(killApp);
17825 void sendSystemPackageUpdatedBroadcasts() {
17826 if (isRemovedPackageSystemUpdate) {
17827 sendSystemPackageUpdatedBroadcastsInternal();
17831 void sendSystemPackageAppearedBroadcasts() {
17832 final int packageCount = (appearedChildPackages != null)
17833 ? appearedChildPackages.size() : 0;
17834 for (int i = 0; i < packageCount; i++) {
17835 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
17836 packageSender.sendPackageAddedForNewUsers(installedInfo.name,
17837 true /*sendBootCompleted*/, false /*startReceiver*/,
17838 UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers, null);
17842 private void sendSystemPackageUpdatedBroadcastsInternal() {
17843 Bundle extras = new Bundle(2);
17844 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
17845 extras.putBoolean(Intent.EXTRA_REPLACING, true);
17846 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17847 removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
17848 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17849 removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
17850 packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
17851 null, null, 0, removedPackage, null, null, null);
17852 if (installerPackageName != null) {
17853 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17854 removedPackage, extras, 0 /*flags*/,
17855 installerPackageName, null, null, null);
17856 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17857 removedPackage, extras, 0 /*flags*/,
17858 installerPackageName, null, null, null);
17862 private void sendPackageRemovedBroadcastInternal(boolean killApp) {
17863 // Don't send static shared library removal broadcasts as these
17864 // libs are visible only the the apps that depend on them an one
17865 // cannot remove the library if it has a dependency.
17866 if (isStaticSharedLib) {
17869 Bundle extras = new Bundle(2);
17870 final int removedUid = removedAppId >= 0 ? removedAppId : uid;
17871 extras.putInt(Intent.EXTRA_UID, removedUid);
17872 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
17873 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
17874 if (isUpdate || isRemovedPackageSystemUpdate) {
17875 extras.putBoolean(Intent.EXTRA_REPLACING, true);
17877 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
17878 if (removedPackage != null) {
17879 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17880 removedPackage, extras, 0, null /*targetPackage*/, null,
17881 broadcastUsers, instantUserIds);
17882 if (installerPackageName != null) {
17883 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17884 removedPackage, extras, 0 /*flags*/,
17885 installerPackageName, null, broadcastUsers, instantUserIds);
17887 if (dataRemoved && !isRemovedPackageSystemUpdate) {
17888 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
17889 removedPackage, extras,
17890 Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17891 null, null, broadcastUsers, instantUserIds);
17892 packageSender.notifyPackageRemoved(removedPackage, removedUid);
17895 if (removedAppId >= 0) {
17896 // If a system app's updates are uninstalled the UID is not actually removed. Some
17897 // services need to know the package name affected.
17898 if (extras.getBoolean(Intent.EXTRA_REPLACING, false)) {
17899 extras.putString(Intent.EXTRA_PACKAGE_NAME, removedPackage);
17902 packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
17903 null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17904 null, null, broadcastUsers, instantUserIds);
17908 void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
17909 removedUsers = userIds;
17910 if (removedUsers == null) {
17911 broadcastUsers = null;
17915 broadcastUsers = EMPTY_INT_ARRAY;
17916 instantUserIds = EMPTY_INT_ARRAY;
17917 for (int i = userIds.length - 1; i >= 0; --i) {
17918 final int userId = userIds[i];
17919 if (deletedPackageSetting.getInstantApp(userId)) {
17920 instantUserIds = ArrayUtils.appendInt(instantUserIds, userId);
17922 broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
17929 * This method deletes the package from internal data structures. If the DELETE_KEEP_DATA
17930 * flag is not set, the data directory is removed as well.
17931 * make sure this flag is set for partially installed apps. If not its meaningless to
17932 * delete a partially installed application.
17934 private void removePackageDataLIF(final PackageSetting deletedPs, int[] allUserHandles,
17935 PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
17936 String packageName = deletedPs.name;
17937 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + deletedPs);
17938 // Retrieve object to delete permissions for shared user later on
17939 final AndroidPackage deletedPkg = deletedPs.pkg;
17940 if (outInfo != null) {
17941 outInfo.removedPackage = packageName;
17942 outInfo.installerPackageName = deletedPs.installSource.installerPackageName;
17943 outInfo.isStaticSharedLib = deletedPkg != null
17944 && deletedPkg.getStaticSharedLibName() != null;
17945 outInfo.populateUsers(deletedPs == null ? null
17946 : deletedPs.queryInstalledUsers(mUserManager.getUserIds(), true), deletedPs);
17949 removePackageLI(deletedPs.name, (flags & PackageManager.DELETE_CHATTY) != 0);
17951 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
17952 final AndroidPackage resolvedPkg;
17953 if (deletedPkg != null) {
17954 resolvedPkg = deletedPkg;
17956 // We don't have a parsed package when it lives on an ejected
17957 // adopted storage device, so fake something together
17958 resolvedPkg = PackageImpl.buildFakeForDeletion(deletedPs.name,
17959 deletedPs.volumeUuid);
17961 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
17962 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
17963 destroyAppProfilesLIF(resolvedPkg);
17964 if (outInfo != null) {
17965 outInfo.dataRemoved = true;
17969 int removedAppId = -1;
17972 boolean installedStateChanged = false;
17973 if (deletedPs != null) {
17974 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
17975 final SparseBooleanArray changedUsers = new SparseBooleanArray();
17976 synchronized (mLock) {
17977 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
17978 clearDefaultBrowserIfNeeded(packageName);
17979 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
17980 removedAppId = mSettings.removePackageLPw(packageName);
17981 if (outInfo != null) {
17982 outInfo.removedAppId = removedAppId;
17984 mPermissionManager.updatePermissions(deletedPs.name, null);
17985 if (deletedPs.sharedUser != null) {
17986 // Remove permissions associated with package. Since runtime
17987 // permissions are per user we have to kill the removed package
17988 // or packages running under the shared user of the removed
17989 // package if revoking the permissions requested only by the removed
17990 // package is successful and this causes a change in gids.
17991 boolean shouldKill = false;
17992 for (int userId : UserManagerService.getInstance().getUserIds()) {
17993 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
17995 shouldKill |= userIdToKill == UserHandle.USER_ALL
17996 || userIdToKill >= UserHandle.USER_SYSTEM;
17998 // If gids changed, kill all affected packages.
18000 mHandler.post(() -> {
18001 // This has to happen with no lock held.
18002 killApplication(deletedPs.name, deletedPs.appId,
18003 KILL_APP_REASON_GIDS_CHANGED);
18007 clearPackagePreferredActivitiesLPw(
18008 deletedPs.name, changedUsers, UserHandle.USER_ALL);
18010 if (changedUsers.size() > 0) {
18011 updateDefaultHomeNotLocked(changedUsers);
18012 postPreferredActivityChangedBroadcast(UserHandle.USER_ALL);
18015 // make sure to preserve per-user disabled state if this removal was just
18016 // a downgrade of a system app to the factory package
18017 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18018 if (DEBUG_REMOVE) {
18019 Slog.d(TAG, "Propagating install state across downgrade");
18021 for (int userId : allUserHandles) {
18022 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18023 if (DEBUG_REMOVE) {
18024 Slog.d(TAG, " user " + userId + " => " + installed);
18026 if (installed != deletedPs.getInstalled(userId)) {
18027 installedStateChanged = true;
18029 deletedPs.setInstalled(installed, userId);
18033 synchronized (mLock) {
18034 // can downgrade to reader
18035 if (writeSettings) {
18036 // Save settings now
18037 mSettings.writeLPr();
18039 if (installedStateChanged) {
18040 mSettings.writeKernelMappingLPr(deletedPs);
18043 if (removedAppId != -1) {
18044 // A user ID was deleted here. Go through all users and remove it
18046 removeKeystoreDataIfNeeded(
18047 mInjector.getUserManagerInternal(), UserHandle.USER_ALL, removedAppId);
18051 private static @Nullable ScanPartition resolveApexToScanPartition(
18052 ApexManager.ActiveApexInfo apexInfo) {
18053 for (int i = 0, size = SYSTEM_PARTITIONS.size(); i < size; i++) {
18054 ScanPartition sp = SYSTEM_PARTITIONS.get(i);
18055 if (apexInfo.preInstalledApexPath.getAbsolutePath().startsWith(
18056 sp.folder.getAbsolutePath())) {
18057 return new ScanPartition(apexInfo.apexDirectory, sp, SCAN_AS_APK_IN_APEX);
18064 * Tries to delete system package.
18066 private void deleteSystemPackageLIF(DeletePackageAction action, PackageSetting deletedPs,
18067 int[] allUserHandles, int flags, @Nullable PackageRemovedInfo outInfo,
18068 boolean writeSettings)
18069 throws SystemDeleteException {
18070 final boolean applyUserRestrictions =
18071 (allUserHandles != null) && outInfo != null && (outInfo.origUsers != null);
18072 final AndroidPackage deletedPkg = deletedPs.pkg;
18073 // Confirm if the system package has been updated
18074 // An updated system app can be deleted. This will also have to restore
18075 // the system pkg from system partition
18077 final PackageSetting disabledPs = action.disabledPs;
18078 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.getPackageName()
18079 + " disabledPs=" + disabledPs);
18080 Slog.d(TAG, "Deleting system pkg from data partition");
18082 if (DEBUG_REMOVE) {
18083 if (applyUserRestrictions) {
18084 Slog.d(TAG, "Remembering install states:");
18085 for (int userId : allUserHandles) {
18086 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
18087 Slog.d(TAG, " u=" + userId + " inst=" + finstalled);
18092 if (outInfo != null) {
18093 // Delete the updated package
18094 outInfo.isRemovedPackageSystemUpdate = true;
18097 if (disabledPs.versionCode < deletedPs.versionCode) {
18098 // Delete data for downgrades
18099 flags &= ~PackageManager.DELETE_KEEP_DATA;
18101 // Preserve data by setting flag
18102 flags |= PackageManager.DELETE_KEEP_DATA;
18105 deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
18106 outInfo, writeSettings);
18109 synchronized (mLock) {
18110 // NOTE: The system package always needs to be enabled; even if it's for
18111 // a compressed stub. If we don't, installing the system package fails
18112 // during scan [scanning checks the disabled packages]. We will reverse
18113 // this later, after we've "installed" the stub.
18114 // Reinstate the old system package
18115 enableSystemPackageLPw(disabledPs.pkg);
18116 // Remove any native libraries from the upgraded package.
18117 removeNativeBinariesLI(deletedPs);
18120 // Install the system package
18121 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18123 installPackageFromSystemLIF(disabledPs.codePathString, allUserHandles,
18124 outInfo == null ? null : outInfo.origUsers, deletedPs.getPermissionsState(),
18126 } catch (PackageManagerException e) {
18127 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.getPackageName() + ": "
18129 // TODO(patb): can we avoid this; throw would come from scan...
18130 throw new SystemDeleteException(e);
18132 if (disabledPs.pkg.isStub()) {
18133 // We've re-installed the stub; make sure it's disabled here. If package was
18134 // originally enabled, we'll install the compressed version of the application
18135 // and re-enable it afterward.
18136 final PackageSetting stubPs = mSettings.mPackages.get(deletedPkg.getPackageName());
18137 if (stubPs != null) {
18139 COMPONENT_ENABLED_STATE_DISABLED, UserHandle.USER_SYSTEM, "android");
18146 * Installs a package that's already on the system partition.
18148 private AndroidPackage installPackageFromSystemLIF(@NonNull String codePathString,
18149 @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
18150 @Nullable PermissionsState origPermissionState, boolean writeSettings)
18151 throws PackageManagerException {
18152 @ParseFlags int parseFlags =
18154 | PackageParser.PARSE_MUST_BE_APK
18155 | PackageParser.PARSE_IS_SYSTEM_DIR;
18156 @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
18157 for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
18158 ScanPartition partition = mDirsToScanAsSystem.get(i);
18159 if (partition.containsPath(codePathString)) {
18160 scanFlags |= partition.scanFlag;
18161 if (partition.containsPrivPath(codePathString)) {
18162 scanFlags |= SCAN_AS_PRIVILEGED;
18168 final File codePath = new File(codePathString);
18169 final AndroidPackage pkg =
18170 scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
18172 PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.getPackageName());
18175 // update shared libraries for the newly re-installed system package
18176 updateSharedLibrariesLocked(pkg, pkgSetting, null, null,
18177 Collections.unmodifiableMap(mPackages));
18178 } catch (PackageManagerException e) {
18179 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18182 prepareAppDataAfterInstallLIF(pkg);
18185 synchronized (mLock) {
18186 PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
18188 // Propagate the permissions state as we do not want to drop on the floor
18189 // runtime permissions. The update permissions method below will take
18190 // care of removing obsolete permissions and grant install permissions.
18191 if (origPermissionState != null) {
18192 ps.getPermissionsState().copyFrom(origPermissionState);
18194 mPermissionManager.updatePermissions(pkg.getPackageName(), pkg);
18196 final boolean applyUserRestrictions
18197 = (allUserHandles != null) && (origUserHandles != null);
18198 if (applyUserRestrictions) {
18199 boolean installedStateChanged = false;
18200 if (DEBUG_REMOVE) {
18201 Slog.d(TAG, "Propagating install state across reinstall");
18203 for (int userId : allUserHandles) {
18204 final boolean installed = ArrayUtils.contains(origUserHandles, userId);
18205 if (DEBUG_REMOVE) {
18206 Slog.d(TAG, " user " + userId + " => " + installed);
18208 if (installed != ps.getInstalled(userId)) {
18209 installedStateChanged = true;
18211 ps.setInstalled(installed, userId);
18213 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
18215 // Regardless of writeSettings we need to ensure that this restriction
18216 // state propagation is persisted
18217 mSettings.writeAllUsersPackageRestrictionsLPr();
18218 if (installedStateChanged) {
18219 mSettings.writeKernelMappingLPr(ps);
18222 // can downgrade to reader here
18223 if (writeSettings) {
18224 mSettings.writeLPr();
18230 private void deleteInstalledPackageLIF(PackageSetting ps,
18231 boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18232 PackageRemovedInfo outInfo, boolean writeSettings) {
18233 synchronized (mLock) {
18234 if (outInfo != null) {
18235 outInfo.uid = ps.appId;
18239 // Delete package data from internal structures and also remove data if flag is set
18240 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18242 // Delete application code and resources only for parent packages
18243 if (deleteCodeAndResources && (outInfo != null)) {
18244 outInfo.args = createInstallArgsForExisting(
18245 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(
18246 ps.primaryCpuAbiString, ps.secondaryCpuAbiString));
18247 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18252 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18254 mContext.enforceCallingOrSelfPermission(
18255 android.Manifest.permission.DELETE_PACKAGES, null);
18256 synchronized (mLock) {
18257 // Cannot block uninstall of static shared libs as they are
18258 // considered a part of the using app (emulating static linking).
18259 // Also static libs are installed always on internal storage.
18260 AndroidPackage pkg = mPackages.get(packageName);
18261 if (pkg != null && pkg.getStaticSharedLibName() != null) {
18262 Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18263 + " providing static shared library: " + pkg.getStaticSharedLibName());
18266 mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
18267 mSettings.writePackageRestrictionsLPr(userId);
18273 public boolean getBlockUninstallForUser(String packageName, int userId) {
18274 synchronized (mLock) {
18275 final PackageSetting ps = mSettings.mPackages.get(packageName);
18276 if (ps == null || shouldFilterApplicationLocked(ps, Binder.getCallingUid(), userId)) {
18279 return mSettings.getBlockUninstallLPr(userId, packageName);
18284 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18285 enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
18286 synchronized (mLock) {
18287 PackageSetting ps = mSettings.mPackages.get(packageName);
18289 Log.w(TAG, "Package doesn't exist: " + packageName);
18292 if (systemUserApp) {
18293 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18295 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18297 mSettings.writeLPr();
18302 private static class DeletePackageAction {
18303 public final PackageSetting deletingPs;
18304 public final PackageSetting disabledPs;
18305 public final PackageRemovedInfo outInfo;
18306 public final int flags;
18307 public final UserHandle user;
18309 private DeletePackageAction(PackageSetting deletingPs, PackageSetting disabledPs,
18310 PackageRemovedInfo outInfo, int flags, UserHandle user) {
18311 this.deletingPs = deletingPs;
18312 this.disabledPs = disabledPs;
18313 this.outInfo = outInfo;
18314 this.flags = flags;
18320 * @return a {@link DeletePackageAction} if the provided package and related state may be
18321 * deleted, {@code null} otherwise.
18324 @GuardedBy("mLock")
18325 private static DeletePackageAction mayDeletePackageLocked(
18326 PackageRemovedInfo outInfo, PackageSetting ps, @Nullable PackageSetting disabledPs,
18327 int flags, UserHandle user) {
18331 if (isSystemApp(ps)) {
18332 final boolean deleteSystem = (flags & PackageManager.DELETE_SYSTEM_APP) != 0;
18333 final boolean deleteAllUsers =
18334 user == null || user.getIdentifier() == UserHandle.USER_ALL;
18335 if ((!deleteSystem || deleteAllUsers) && disabledPs == null) {
18336 Slog.w(TAG, "Attempt to delete unknown system package " + ps.pkg.getPackageName());
18339 // Confirmed if the system package has been updated
18340 // An updated system app can be deleted. This will also have to restore
18341 // the system pkg from system partition reader
18343 return new DeletePackageAction(ps, disabledPs, outInfo, flags, user);
18347 * This method handles package deletion in general
18349 private boolean deletePackageLIF(@NonNull String packageName, UserHandle user,
18350 boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18351 PackageRemovedInfo outInfo, boolean writeSettings,
18352 ParsedPackage replacingPackage) {
18353 final DeletePackageAction action;
18354 synchronized (mLock) {
18355 final PackageSetting ps = mSettings.mPackages.get(packageName);
18356 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
18357 action = mayDeletePackageLocked(outInfo, ps, disabledPs, flags, user);
18359 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18360 if (null == action) {
18361 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: action was null");
18367 executeDeletePackageLIF(action, packageName, deleteCodeAndResources,
18368 allUserHandles, writeSettings, replacingPackage);
18369 } catch (SystemDeleteException e) {
18370 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: system deletion failure", e);
18376 private static class SystemDeleteException extends Exception {
18377 public final PackageManagerException reason;
18379 private SystemDeleteException(PackageManagerException reason) {
18380 this.reason = reason;
18384 /** Deletes a package. Only throws when install of a disabled package fails. */
18385 private void executeDeletePackageLIF(DeletePackageAction action,
18386 String packageName, boolean deleteCodeAndResources,
18387 int[] allUserHandles, boolean writeSettings,
18388 ParsedPackage replacingPackage) throws SystemDeleteException {
18389 final PackageSetting ps = action.deletingPs;
18390 final PackageRemovedInfo outInfo = action.outInfo;
18391 final UserHandle user = action.user;
18392 final int flags = action.flags;
18393 final boolean systemApp = isSystemApp(ps);
18395 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
18396 if (ps.getPermissionsState().hasPermission(Manifest.permission.SUSPEND_APPS, userId)) {
18397 unsuspendForSuspendingPackage(packageName, userId);
18399 if ((!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)
18400 && userId != UserHandle.USER_ALL) {
18401 // The caller is asking that the package only be deleted for a single
18402 // user. To do this, we just mark its uninstalled state and delete
18403 // its data. If this is a system app, we only allow this to happen if
18404 // they have set the special DELETE_SYSTEM_APP which requests different
18405 // semantics than normal for uninstalling system apps.
18406 final boolean clearPackageStateAndReturn;
18407 synchronized (mLock) {
18408 markPackageUninstalledForUserLPw(ps, user);
18410 // Do not uninstall the APK if an app should be cached
18411 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18412 if (ps.isAnyInstalled(mUserManager.getUserIds()) || keepUninstalledPackage) {
18413 // Other users still have this package installed, so all
18414 // we need to do is clear this user's data and save that
18415 // it is uninstalled.
18416 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18417 clearPackageStateAndReturn = true;
18419 // We need to set it back to 'installed' so the uninstall
18420 // broadcasts will be sent correctly.
18421 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18422 ps.setInstalled(true, userId);
18423 mSettings.writeKernelMappingLPr(ps);
18424 clearPackageStateAndReturn = false;
18427 // This is a system app, so we assume that the
18428 // other users still have this package installed, so all
18429 // we need to do is clear this user's data and save that
18430 // it is uninstalled.
18431 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18432 clearPackageStateAndReturn = true;
18435 if (clearPackageStateAndReturn) {
18436 clearPackageStateForUserLIF(ps, userId, outInfo, flags);
18437 synchronized (mLock) {
18438 scheduleWritePackageRestrictionsLocked(user);
18444 // TODO(b/109941548): break reasons for ret = false out into mayDelete method
18446 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18447 // When an updated system application is deleted we delete the existing resources
18448 // as well and fall back to existing code in system partition
18449 deleteSystemPackageLIF(action, ps, allUserHandles, flags, outInfo, writeSettings);
18451 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18452 deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18453 outInfo, writeSettings);
18456 // Take a note whether we deleted the package for all users
18457 if (outInfo != null) {
18458 outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18462 @GuardedBy("mLock")
18463 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18464 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18465 ? mUserManager.getUserIds() : new int[] {user.getIdentifier()};
18466 for (int nextUserId : userIds) {
18467 if (DEBUG_REMOVE) {
18468 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18470 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18471 false /*installed*/,
18473 true /*notLaunched*/,
18475 0 /*distractionFlags*/,
18476 false /*suspended*/,
18477 null /*suspendParams*/,
18478 false /*instantApp*/,
18479 false /*virtualPreload*/,
18480 null /*lastDisableAppCaller*/,
18481 null /*enabledComponents*/,
18482 null /*disabledComponents*/,
18483 ps.readUserState(nextUserId).domainVerificationStatus,
18484 0, PackageManager.INSTALL_REASON_UNKNOWN,
18485 null /*harmfulAppWarning*/);
18487 mSettings.writeKernelMappingLPr(ps);
18490 private void clearPackageStateForUserLIF(PackageSetting ps, int userId,
18491 PackageRemovedInfo outInfo, int flags) {
18492 final AndroidPackage pkg;
18493 synchronized (mLock) {
18494 pkg = mPackages.get(ps.name);
18497 destroyAppProfilesLIF(pkg);
18499 final int[] userIds = (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds()
18500 : new int[] {userId};
18501 for (int nextUserId : userIds) {
18502 if (DEBUG_REMOVE) {
18503 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18507 destroyAppDataLIF(pkg, nextUserId,
18508 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
18509 clearDefaultBrowserIfNeededForUser(ps.name, nextUserId);
18510 removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), nextUserId, ps.appId);
18511 clearPackagePreferredActivities(ps.name, nextUserId);
18512 mPermissionManager.resetRuntimePermissions(pkg, nextUserId);
18515 if (outInfo != null) {
18516 outInfo.removedPackage = ps.name;
18517 outInfo.installerPackageName = ps.installSource.installerPackageName;
18518 outInfo.isStaticSharedLib = pkg != null && pkg.getStaticSharedLibName() != null;
18519 outInfo.removedAppId = ps.appId;
18520 outInfo.removedUsers = userIds;
18521 outInfo.broadcastUsers = userIds;
18526 public void clearApplicationProfileData(String packageName) {
18527 enforceSystemOrRoot("Only the system can clear all profile data");
18529 final AndroidPackage pkg;
18530 synchronized (mLock) {
18531 pkg = mPackages.get(packageName);
18534 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
18535 synchronized (mInstallLock) {
18536 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
18542 public void clearApplicationUserData(final String packageName,
18543 final IPackageDataObserver observer, final int userId) {
18544 mContext.enforceCallingOrSelfPermission(
18545 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
18547 final int callingUid = Binder.getCallingUid();
18548 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18549 true /* requireFullPermission */, false /* checkShell */, "clear application data");
18551 final PackageSetting ps = mSettings.getPackageLPr(packageName);
18552 final boolean filterApp =
18553 (ps != null && shouldFilterApplicationLocked(ps, callingUid, userId));
18554 if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
18555 throw new SecurityException("Cannot clear data for a protected package: "
18558 // Queue up an async operation since the package deletion may take a little while.
18559 mHandler.post(new Runnable() {
18560 public void run() {
18561 mHandler.removeCallbacks(this);
18562 final boolean succeeded;
18564 try (PackageFreezer freezer = freezePackage(packageName,
18565 "clearApplicationUserData")) {
18566 synchronized (mInstallLock) {
18567 succeeded = clearApplicationUserDataLIF(packageName, userId);
18569 synchronized (mLock) {
18570 mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
18571 packageName, userId);
18575 // invoke DeviceStorageMonitor's update method to clear any notifications
18576 DeviceStorageMonitorInternal dsm = LocalServices
18577 .getService(DeviceStorageMonitorInternal.class);
18581 if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
18582 == PERMISSION_GRANTED) {
18583 unsuspendForSuspendingPackage(packageName, userId);
18584 removeAllDistractingPackageRestrictions(userId);
18585 flushPackageRestrictionsAsUserInternalLocked(userId);
18591 if (observer != null) {
18593 observer.onRemoveCompleted(packageName, succeeded);
18594 } catch (RemoteException e) {
18595 Log.i(TAG, "Observer no longer exists.");
18597 } //end if observer
18602 private boolean clearApplicationUserDataLIF(String packageName, int userId) {
18603 if (packageName == null) {
18604 Slog.w(TAG, "Attempt to delete null packageName.");
18608 // Try finding details about the requested package
18609 AndroidPackage pkg;
18611 synchronized (mLock) {
18612 pkg = mPackages.get(packageName);
18613 ps = mSettings.mPackages.get(packageName);
18621 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18624 mPermissionManager.resetRuntimePermissions(pkg, userId);
18626 clearAppDataLIF(pkg, userId,
18627 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
18629 final int appId = UserHandle.getAppId(pkg.getUid());
18630 removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), userId, appId);
18632 UserManagerInternal umInternal = mInjector.getUserManagerInternal();
18634 if (umInternal.isUserUnlockingOrUnlocked(userId)) {
18635 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18636 } else if (umInternal.isUserRunning(userId)) {
18637 flags = StorageManager.FLAG_STORAGE_DE;
18641 prepareAppDataContentsLIF(pkg, ps, userId, flags);
18646 private void resetNetworkPolicies(int userId) {
18647 mInjector.getNetworkPolicyManagerInternal().resetUserState(userId);
18651 * Remove entries from the keystore daemon. Will only remove it if the
18652 * {@code appId} is valid.
18654 private static void removeKeystoreDataIfNeeded(UserManagerInternal um, @UserIdInt int userId,
18655 @AppIdInt int appId) {
18660 final KeyStore keyStore = KeyStore.getInstance();
18661 if (keyStore != null) {
18662 if (userId == UserHandle.USER_ALL) {
18663 for (final int individual : um.getUserIds()) {
18664 keyStore.clearUid(UserHandle.getUid(individual, appId));
18667 keyStore.clearUid(UserHandle.getUid(userId, appId));
18670 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
18675 public void deleteApplicationCacheFiles(final String packageName,
18676 final IPackageDataObserver observer) {
18677 final int userId = UserHandle.getCallingUserId();
18678 deleteApplicationCacheFilesAsUser(packageName, userId, observer);
18682 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
18683 final IPackageDataObserver observer) {
18684 final int callingUid = Binder.getCallingUid();
18685 if (mContext.checkCallingOrSelfPermission(
18686 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES)
18687 != PackageManager.PERMISSION_GRANTED) {
18688 // If the caller has the old delete cache permission, silently ignore. Else throw.
18689 if (mContext.checkCallingOrSelfPermission(
18690 android.Manifest.permission.DELETE_CACHE_FILES)
18691 == PackageManager.PERMISSION_GRANTED) {
18692 Slog.w(TAG, "Calling uid " + callingUid + " does not have " +
18693 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES +
18694 ", silently ignoring");
18697 mContext.enforceCallingOrSelfPermission(
18698 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
18700 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18701 /* requireFullPermission= */ true, /* checkShell= */ false,
18702 "delete application cache files");
18703 final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
18704 android.Manifest.permission.ACCESS_INSTANT_APPS);
18706 final AndroidPackage pkg;
18707 synchronized (mLock) {
18708 pkg = mPackages.get(packageName);
18711 // Queue up an async operation since the package deletion may take a little while.
18712 mHandler.post(() -> {
18713 final PackageSetting ps = pkg == null ? null : getPackageSetting(pkg.getPackageName());
18714 boolean doClearData = true;
18716 final boolean targetIsInstantApp =
18717 ps.getInstantApp(UserHandle.getUserId(callingUid));
18718 doClearData = !targetIsInstantApp
18719 || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
18722 synchronized (mInstallLock) {
18723 final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL;
18724 // We're only clearing cache files, so we don't care if the
18725 // app is unfrozen and still able to run
18726 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
18727 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18730 if (observer != null) {
18732 observer.onRemoveCompleted(packageName, true);
18733 } catch (RemoteException e) {
18734 Log.i(TAG, "Observer no longer exists.");
18741 public void getPackageSizeInfo(final String packageName, int userId,
18742 final IPackageStatsObserver observer) {
18743 throw new UnsupportedOperationException(
18744 "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
18747 @GuardedBy("mInstallLock")
18748 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
18749 final PackageSetting ps;
18750 synchronized (mLock) {
18751 ps = mSettings.mPackages.get(packageName);
18753 Slog.w(TAG, "Failed to find settings for " + packageName);
18758 final String[] packageNames = { packageName };
18759 final long[] ceDataInodes = { ps.getCeDataInode(userId) };
18760 final String[] codePaths = { ps.codePathString };
18763 mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
18764 ps.appId, ceDataInodes, codePaths, stats);
18766 // For now, ignore code size of packages on system partition
18767 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
18768 stats.codeSize = 0;
18771 // External clients expect these to be tracked separately
18772 stats.dataSize -= stats.cacheSize;
18774 } catch (InstallerException e) {
18775 Slog.w(TAG, String.valueOf(e));
18782 @GuardedBy("mLock")
18783 private int getUidTargetSdkVersionLockedLPr(int uid) {
18784 final int appId = UserHandle.getAppId(uid);
18785 final Object obj = mSettings.getSettingLPr(appId);
18786 if (obj instanceof SharedUserSetting) {
18787 final SharedUserSetting sus = (SharedUserSetting) obj;
18788 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
18789 final Iterator<PackageSetting> it = sus.packages.iterator();
18790 while (it.hasNext()) {
18791 final PackageSetting ps = it.next();
18792 if (ps.pkg != null) {
18793 int v = ps.pkg.getTargetSdkVersion();
18794 if (v < vers) vers = v;
18798 } else if (obj instanceof PackageSetting) {
18799 final PackageSetting ps = (PackageSetting) obj;
18800 if (ps.pkg != null) {
18801 return ps.pkg.getTargetSdkVersion();
18804 return Build.VERSION_CODES.CUR_DEVELOPMENT;
18807 @GuardedBy("mLock")
18808 private int getPackageTargetSdkVersionLockedLPr(String packageName) {
18809 final AndroidPackage p = mPackages.get(packageName);
18811 return p.getTargetSdkVersion();
18813 return Build.VERSION_CODES.CUR_DEVELOPMENT;
18817 public void addPreferredActivity(IntentFilter filter, int match,
18818 ComponentName[] set, ComponentName activity, int userId) {
18819 addPreferredActivityInternal(filter, match, set, activity, true, userId,
18820 "Adding preferred");
18823 private void addPreferredActivityInternal(IntentFilter filter, int match,
18824 ComponentName[] set, ComponentName activity, boolean always, int userId,
18827 int callingUid = Binder.getCallingUid();
18828 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18829 true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
18830 if (mContext.checkCallingOrSelfPermission(
18831 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18832 != PackageManager.PERMISSION_GRANTED) {
18833 if (getUidTargetSdkVersionLockedLPr(callingUid)
18834 < Build.VERSION_CODES.FROYO) {
18835 Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
18839 mContext.enforceCallingOrSelfPermission(
18840 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18842 if (filter.countActions() == 0) {
18843 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
18846 if (DEBUG_PREFERRED) {
18847 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
18849 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
18851 synchronized (mLock) {
18852 final PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
18853 pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
18854 scheduleWritePackageRestrictionsLocked(userId);
18856 if (!updateDefaultHomeNotLocked(userId)) {
18857 postPreferredActivityChangedBroadcast(userId);
18861 private void postPreferredActivityChangedBroadcast(int userId) {
18862 mHandler.post(() -> {
18863 final IActivityManager am = ActivityManager.getService();
18868 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
18869 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18870 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
18872 am.broadcastIntentWithFeature(null, null, intent, null, null,
18873 0, null, null, null, android.app.AppOpsManager.OP_NONE,
18874 null, false, false, userId);
18875 } catch (RemoteException e) {
18881 public void replacePreferredActivity(IntentFilter filter, int match,
18882 ComponentName[] set, ComponentName activity, int userId) {
18883 if (filter.countActions() != 1) {
18884 throw new IllegalArgumentException(
18885 "replacePreferredActivity expects filter to have only 1 action.");
18887 if (filter.countDataAuthorities() != 0
18888 || filter.countDataPaths() != 0
18889 || filter.countDataSchemes() > 1
18890 || filter.countDataTypes() != 0) {
18891 throw new IllegalArgumentException(
18892 "replacePreferredActivity expects filter to have no data authorities, " +
18893 "paths, or types; and at most one scheme.");
18896 final int callingUid = Binder.getCallingUid();
18897 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18898 true /* requireFullPermission */, false /* checkShell */,
18899 "replace preferred activity");
18900 if (mContext.checkCallingOrSelfPermission(
18901 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18902 != PackageManager.PERMISSION_GRANTED) {
18903 synchronized (mLock) {
18904 if (getUidTargetSdkVersionLockedLPr(callingUid)
18905 < Build.VERSION_CODES.FROYO) {
18906 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
18907 + Binder.getCallingUid());
18911 mContext.enforceCallingOrSelfPermission(
18912 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18915 synchronized (mLock) {
18916 final PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
18918 // Get all of the existing entries that exactly match this filter.
18919 final ArrayList<PreferredActivity> existing = pir.findFilters(filter);
18920 if (existing != null && existing.size() == 1) {
18921 final PreferredActivity cur = existing.get(0);
18922 if (DEBUG_PREFERRED) {
18923 Slog.i(TAG, "Checking replace of preferred:");
18924 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
18925 if (!cur.mPref.mAlways) {
18926 Slog.i(TAG, " -- CUR; not mAlways!");
18928 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch);
18929 Slog.i(TAG, " -- CUR: mSet="
18930 + Arrays.toString(cur.mPref.mSetComponents));
18931 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent);
18932 Slog.i(TAG, " -- NEW: mMatch="
18933 + (match&IntentFilter.MATCH_CATEGORY_MASK));
18934 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set));
18935 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString());
18938 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
18939 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
18940 && cur.mPref.sameSet(set)) {
18941 // Setting the preferred activity to what it happens to be already
18942 if (DEBUG_PREFERRED) {
18943 Slog.i(TAG, "Replacing with same preferred activity "
18944 + cur.mPref.mShortComponent + " for user "
18946 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
18951 if (existing != null) {
18952 if (DEBUG_PREFERRED) {
18953 Slog.i(TAG, existing.size() + " existing preferred matches for:");
18954 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
18956 for (int i = existing.size() - 1; i >= 0; --i) {
18957 final PreferredActivity pa = existing.get(i);
18958 if (DEBUG_PREFERRED) {
18959 Slog.i(TAG, "Removing existing preferred activity "
18960 + pa.mPref.mComponent + ":");
18961 pa.dump(new LogPrinter(Log.INFO, TAG), " ");
18963 pir.removeFilter(pa);
18968 addPreferredActivityInternal(filter, match, set, activity, true, userId,
18969 "Replacing preferred");
18973 public void clearPackagePreferredActivities(String packageName) {
18974 final int callingUid = Binder.getCallingUid();
18975 if (getInstantAppPackageName(callingUid) != null) {
18979 synchronized (mLock) {
18980 AndroidPackage pkg = mPackages.get(packageName);
18981 if (pkg == null || !isCallerSameApp(packageName, callingUid)) {
18982 if (mContext.checkCallingOrSelfPermission(
18983 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18984 != PackageManager.PERMISSION_GRANTED) {
18985 if (getUidTargetSdkVersionLockedLPr(callingUid)
18986 < Build.VERSION_CODES.FROYO) {
18987 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
18991 mContext.enforceCallingOrSelfPermission(
18992 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18995 final PackageSetting ps = mSettings.getPackageLPr(packageName);
18997 && shouldFilterApplicationLocked(
18998 ps, callingUid, UserHandle.getUserId(callingUid))) {
19002 int callingUserId = UserHandle.getCallingUserId();
19003 clearPackagePreferredActivities(packageName, callingUserId);
19006 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19007 private void clearPackagePreferredActivities(String packageName, int userId) {
19008 final SparseBooleanArray changedUsers = new SparseBooleanArray();
19010 clearPackagePreferredActivitiesLPw(packageName, changedUsers, userId);
19011 if (changedUsers.size() > 0) {
19012 updateDefaultHomeNotLocked(changedUsers);
19013 postPreferredActivityChangedBroadcast(userId);
19014 synchronized (mLock) {
19015 scheduleWritePackageRestrictionsLocked(userId);
19020 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19021 @GuardedBy("mLock")
19022 private void clearPackagePreferredActivitiesLPw(String packageName,
19023 @NonNull SparseBooleanArray outUserChanged, int userId) {
19024 ArrayList<PreferredActivity> removed = null;
19025 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19026 final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19027 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19028 if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19031 Iterator<PreferredActivity> it = pir.filterIterator();
19032 while (it.hasNext()) {
19033 PreferredActivity pa = it.next();
19034 // Mark entry for removal only if it matches the package name
19035 // and the entry is of type "always".
19036 if (packageName == null ||
19037 (pa.mPref.mComponent.getPackageName().equals(packageName)
19038 && pa.mPref.mAlways)) {
19039 if (removed == null) {
19040 removed = new ArrayList<>();
19045 if (removed != null) {
19046 for (int j=0; j<removed.size(); j++) {
19047 PreferredActivity pa = removed.get(j);
19048 pir.removeFilter(pa);
19050 outUserChanged.put(thisUserId, true);
19055 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19056 @GuardedBy("mLock")
19057 private void clearIntentFilterVerificationsLPw(int userId) {
19058 final int packageCount = mPackages.size();
19059 for (int i = 0; i < packageCount; i++) {
19060 AndroidPackage pkg = mPackages.valueAt(i);
19061 clearIntentFilterVerificationsLPw(pkg.getPackageName(), userId);
19065 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19066 @GuardedBy("mLock")
19067 void clearIntentFilterVerificationsLPw(String packageName, int userId) {
19068 if (userId == UserHandle.USER_ALL) {
19069 if (mSettings.removeIntentFilterVerificationLPw(packageName,
19070 mUserManager.getUserIds())) {
19071 for (int oneUserId : mUserManager.getUserIds()) {
19072 scheduleWritePackageRestrictionsLocked(oneUserId);
19076 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
19077 scheduleWritePackageRestrictionsLocked(userId);
19082 /** Clears state for all users, and touches intent filter verification policy */
19083 void clearDefaultBrowserIfNeeded(String packageName) {
19084 for (int oneUserId : mUserManager.getUserIds()) {
19085 clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
19089 private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
19090 final String defaultBrowserPackageName = mPermissionManager.getDefaultBrowser(userId);
19091 if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
19092 if (packageName.equals(defaultBrowserPackageName)) {
19093 mPermissionManager.setDefaultBrowser(null, true, true, userId);
19099 public void resetApplicationPreferences(int userId) {
19100 mContext.enforceCallingOrSelfPermission(
19101 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19102 final long identity = Binder.clearCallingIdentity();
19105 final SparseBooleanArray changedUsers = new SparseBooleanArray();
19106 clearPackagePreferredActivitiesLPw(null, changedUsers, userId);
19107 if (changedUsers.size() > 0) {
19108 postPreferredActivityChangedBroadcast(userId);
19110 synchronized (mLock) {
19111 mSettings.applyDefaultPreferredAppsLPw(userId);
19112 clearIntentFilterVerificationsLPw(userId);
19113 primeDomainVerificationsLPw(userId);
19115 mPermissionManager.resetAllRuntimePermissions(userId);
19116 updateDefaultHomeNotLocked(userId);
19117 // TODO: We have to reset the default SMS and Phone. This requires
19118 // significant refactoring to keep all default apps in the package
19119 // manager (cleaner but more work) or have the services provide
19120 // callbacks to the package manager to request a default app reset.
19121 mPermissionManager.setDefaultBrowser(null, true, true, userId);
19122 resetNetworkPolicies(userId);
19123 synchronized (mLock) {
19124 scheduleWritePackageRestrictionsLocked(userId);
19127 Binder.restoreCallingIdentity(identity);
19132 public int getPreferredActivities(List<IntentFilter> outFilters,
19133 List<ComponentName> outActivities, String packageName) {
19134 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19138 final int userId = UserHandle.getCallingUserId();
19140 synchronized (mLock) {
19141 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19143 final Iterator<PreferredActivity> it = pir.filterIterator();
19144 while (it.hasNext()) {
19145 final PreferredActivity pa = it.next();
19146 if (packageName == null
19147 || (pa.mPref.mComponent.getPackageName().equals(packageName)
19148 && pa.mPref.mAlways)) {
19149 if (outFilters != null) {
19150 outFilters.add(new IntentFilter(pa));
19152 if (outActivities != null) {
19153 outActivities.add(pa.mPref.mComponent);
19164 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19166 int callingUid = Binder.getCallingUid();
19167 if (callingUid != Process.SYSTEM_UID) {
19168 throw new SecurityException(
19169 "addPersistentPreferredActivity can only be run by the system");
19171 if (filter.countActions() == 0) {
19172 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19175 if (DEBUG_PREFERRED) {
19176 Slog.i(TAG, "Adding persistent preferred activity " + activity
19177 + " for user " + userId + ":");
19178 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
19180 synchronized (mLock) {
19181 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19182 new PersistentPreferredActivity(filter, activity));
19183 scheduleWritePackageRestrictionsLocked(userId);
19185 updateDefaultHomeNotLocked(userId);
19186 postPreferredActivityChangedBroadcast(userId);
19190 public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19191 int callingUid = Binder.getCallingUid();
19192 if (callingUid != Process.SYSTEM_UID) {
19193 throw new SecurityException(
19194 "clearPackagePersistentPreferredActivities can only be run by the system");
19196 ArrayList<PersistentPreferredActivity> removed = null;
19197 boolean changed = false;
19198 synchronized (mLock) {
19199 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19200 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19201 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19203 if (userId != thisUserId) {
19206 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19207 while (it.hasNext()) {
19208 PersistentPreferredActivity ppa = it.next();
19209 // Mark entry for removal only if it matches the package name.
19210 if (ppa.mComponent.getPackageName().equals(packageName)) {
19211 if (removed == null) {
19212 removed = new ArrayList<>();
19217 if (removed != null) {
19218 for (int j=0; j<removed.size(); j++) {
19219 PersistentPreferredActivity ppa = removed.get(j);
19220 ppir.removeFilter(ppa);
19227 updateDefaultHomeNotLocked(userId);
19228 postPreferredActivityChangedBroadcast(userId);
19229 synchronized (mLock) {
19230 scheduleWritePackageRestrictionsLocked(userId);
19236 * Common machinery for picking apart a restored XML blob and passing
19237 * it to a caller-supplied functor to be applied to the running system.
19239 private void restoreFromXml(XmlPullParser parser, int userId,
19240 String expectedStartTag, BlobXmlRestorer functor)
19241 throws IOException, XmlPullParserException {
19243 while ((type = parser.next()) != XmlPullParser.START_TAG
19244 && type != XmlPullParser.END_DOCUMENT) {
19246 if (type != XmlPullParser.START_TAG) {
19247 // oops didn't find a start tag?!
19248 if (DEBUG_BACKUP) {
19249 Slog.e(TAG, "Didn't find start tag during restore");
19253 // this is supposed to be TAG_PREFERRED_BACKUP
19254 if (!expectedStartTag.equals(parser.getName())) {
19255 if (DEBUG_BACKUP) {
19256 Slog.e(TAG, "Found unexpected tag " + parser.getName());
19261 // skip interfering stuff, then we're aligned with the backing implementation
19262 while ((type = parser.next()) == XmlPullParser.TEXT) { }
19263 functor.apply(parser, userId);
19266 private interface BlobXmlRestorer {
19267 void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19271 * Non-Binder method, support for the backup/restore mechanism: write the
19272 * full set of preferred activities in its canonical XML format. Returns the
19273 * XML output as a byte array, or null if there is none.
19276 public byte[] getPreferredActivityBackup(int userId) {
19277 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19278 throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19281 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19283 final XmlSerializer serializer = new FastXmlSerializer();
19284 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19285 serializer.startDocument(null, true);
19286 serializer.startTag(null, TAG_PREFERRED_BACKUP);
19288 synchronized (mLock) {
19289 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19292 serializer.endTag(null, TAG_PREFERRED_BACKUP);
19293 serializer.endDocument();
19294 serializer.flush();
19295 } catch (Exception e) {
19296 if (DEBUG_BACKUP) {
19297 Slog.e(TAG, "Unable to write preferred activities for backup", e);
19302 return dataStream.toByteArray();
19306 public void restorePreferredActivities(byte[] backup, int userId) {
19307 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19308 throw new SecurityException("Only the system may call restorePreferredActivities()");
19312 final XmlPullParser parser = Xml.newPullParser();
19313 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19314 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19315 (readParser, readUserId) -> {
19316 synchronized (mLock) {
19317 mSettings.readPreferredActivitiesLPw(readParser, readUserId);
19319 updateDefaultHomeNotLocked(readUserId);
19321 } catch (Exception e) {
19322 if (DEBUG_BACKUP) {
19323 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19329 * Non-Binder method, support for the backup/restore mechanism: write the
19330 * default browser (etc) settings in its canonical XML format. Returns the default
19331 * browser XML representation as a byte array, or null if there is none.
19334 public byte[] getDefaultAppsBackup(int userId) {
19335 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19336 throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19339 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19341 final XmlSerializer serializer = new FastXmlSerializer();
19342 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19343 serializer.startDocument(null, true);
19344 serializer.startTag(null, TAG_DEFAULT_APPS);
19346 synchronized (mLock) {
19347 mSettings.writeDefaultAppsLPr(serializer, userId);
19350 serializer.endTag(null, TAG_DEFAULT_APPS);
19351 serializer.endDocument();
19352 serializer.flush();
19353 } catch (Exception e) {
19354 if (DEBUG_BACKUP) {
19355 Slog.e(TAG, "Unable to write default apps for backup", e);
19360 return dataStream.toByteArray();
19364 public void restoreDefaultApps(byte[] backup, int userId) {
19365 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19366 throw new SecurityException("Only the system may call restoreDefaultApps()");
19370 final XmlPullParser parser = Xml.newPullParser();
19371 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19372 restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19373 (parser1, userId1) -> {
19374 final String defaultBrowser;
19375 synchronized (mLock) {
19376 mSettings.readDefaultAppsLPw(parser1, userId1);
19377 defaultBrowser = mSettings.removeDefaultBrowserPackageNameLPw(userId1);
19379 if (defaultBrowser != null) {
19381 .setDefaultBrowser(defaultBrowser, false, false, userId1);
19384 } catch (Exception e) {
19385 if (DEBUG_BACKUP) {
19386 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19392 public byte[] getIntentFilterVerificationBackup(int userId) {
19393 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19394 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19397 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19399 final XmlSerializer serializer = new FastXmlSerializer();
19400 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19401 serializer.startDocument(null, true);
19402 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19404 synchronized (mLock) {
19405 mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19408 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19409 serializer.endDocument();
19410 serializer.flush();
19411 } catch (Exception e) {
19412 if (DEBUG_BACKUP) {
19413 Slog.e(TAG, "Unable to write default apps for backup", e);
19418 return dataStream.toByteArray();
19422 public void restoreIntentFilterVerification(byte[] backup, int userId) {
19423 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19424 throw new SecurityException("Only the system may call restorePreferredActivities()");
19428 final XmlPullParser parser = Xml.newPullParser();
19429 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19430 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19431 (parser1, userId1) -> {
19432 synchronized (mLock) {
19433 mSettings.readAllDomainVerificationsLPr(parser1, userId1);
19434 mSettings.writeLPr();
19437 } catch (Exception e) {
19438 if (DEBUG_BACKUP) {
19439 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19445 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
19446 int sourceUserId, int targetUserId, int flags) {
19447 mContext.enforceCallingOrSelfPermission(
19448 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19449 int callingUid = Binder.getCallingUid();
19450 enforceOwnerRights(ownerPackage, callingUid);
19451 PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
19452 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19453 if (intentFilter.countActions() == 0) {
19454 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
19457 synchronized (mLock) {
19458 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
19459 ownerPackage, targetUserId, flags);
19460 CrossProfileIntentResolver resolver =
19461 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19462 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
19463 // We have all those whose filter is equal. Now checking if the rest is equal as well.
19464 if (existing != null) {
19465 int size = existing.size();
19466 for (int i = 0; i < size; i++) {
19467 if (newFilter.equalsIgnoreFilter(existing.get(i))) {
19472 resolver.addFilter(newFilter);
19473 scheduleWritePackageRestrictionsLocked(sourceUserId);
19478 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
19479 mContext.enforceCallingOrSelfPermission(
19480 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19481 final int callingUid = Binder.getCallingUid();
19482 enforceOwnerRights(ownerPackage, callingUid);
19483 PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
19484 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19485 synchronized (mLock) {
19486 CrossProfileIntentResolver resolver =
19487 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19488 ArraySet<CrossProfileIntentFilter> set =
19489 new ArraySet<>(resolver.filterSet());
19490 for (CrossProfileIntentFilter filter : set) {
19491 if (filter.getOwnerPackage().equals(ownerPackage)) {
19492 resolver.removeFilter(filter);
19495 scheduleWritePackageRestrictionsLocked(sourceUserId);
19499 // Enforcing that callingUid is owning pkg on userId
19500 private void enforceOwnerRights(String pkg, int callingUid) {
19501 // The system owns everything.
19502 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19505 final int callingUserId = UserHandle.getUserId(callingUid);
19506 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
19508 throw new IllegalArgumentException("Unknown package " + pkg + " on user "
19511 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
19512 throw new SecurityException("Calling uid " + callingUid
19513 + " does not own package " + pkg);
19518 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
19519 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19522 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
19526 * Send a {@code PackageInstaller.ACTION_SESSION_UPDATED} broadcast intent, containing
19527 * the {@code sessionInfo} in the extra field {@code PackageInstaller.EXTRA_SESSION}.
19529 public void sendSessionUpdatedBroadcast(PackageInstaller.SessionInfo sessionInfo,
19531 if (TextUtils.isEmpty(sessionInfo.installerPackageName)) {
19534 Intent sessionUpdatedIntent = new Intent(PackageInstaller.ACTION_SESSION_UPDATED)
19535 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
19536 .setPackage(sessionInfo.installerPackageName);
19537 mContext.sendBroadcastAsUser(sessionUpdatedIntent, UserHandle.of(userId));
19540 public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
19541 UserManagerService ums = UserManagerService.getInstance();
19542 if (ums != null && !sessionInfo.isStaged()) {
19543 final UserInfo parent = ums.getProfileParent(userId);
19544 final int launcherUid = (parent != null) ? parent.id : userId;
19545 final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
19546 if (launcherComponent != null) {
19547 Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
19548 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
19549 .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
19550 .setPackage(launcherComponent.getPackageName());
19551 mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
19553 // TODO(b/122900055) Change/Remove this and replace with new permission role.
19554 if (mAppPredictionServicePackage != null) {
19555 Intent predictorIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
19556 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
19557 .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
19558 .setPackage(mAppPredictionServicePackage);
19559 mContext.sendBroadcastAsUser(predictorIntent, UserHandle.of(launcherUid));
19565 * Report the 'Home' activity which is currently set as "always use this one". If non is set
19566 * then reports the most likely home activity or null if there are more than one.
19568 private ComponentName getDefaultHomeActivity(int userId) {
19569 List<ResolveInfo> allHomeCandidates = new ArrayList<>();
19570 ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
19575 // Find the launcher with the highest priority and return that component if there are no
19576 // other home activity with the same priority.
19577 int lastPriority = Integer.MIN_VALUE;
19578 ComponentName lastComponent = null;
19579 final int size = allHomeCandidates.size();
19580 for (int i = 0; i < size; i++) {
19581 final ResolveInfo ri = allHomeCandidates.get(i);
19582 if (ri.priority > lastPriority) {
19583 lastComponent = ri.activityInfo.getComponentName();
19584 lastPriority = ri.priority;
19585 } else if (ri.priority == lastPriority) {
19586 // Two components found with same priority.
19587 lastComponent = null;
19590 return lastComponent;
19593 private Intent getHomeIntent() {
19594 Intent intent = new Intent(Intent.ACTION_MAIN);
19595 intent.addCategory(Intent.CATEGORY_HOME);
19596 intent.addCategory(Intent.CATEGORY_DEFAULT);
19600 private IntentFilter getHomeFilter() {
19601 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
19602 filter.addCategory(Intent.CATEGORY_HOME);
19603 filter.addCategory(Intent.CATEGORY_DEFAULT);
19607 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
19609 Intent intent = getHomeIntent();
19610 List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
19611 PackageManager.GET_META_DATA, userId);
19612 allHomeCandidates.clear();
19613 if (resolveInfos == null) {
19616 allHomeCandidates.addAll(resolveInfos);
19618 final String packageName = mPermissionManager.getDefaultHome(userId);
19619 if (packageName == null) {
19622 int resolveInfosSize = resolveInfos.size();
19623 for (int i = 0; i < resolveInfosSize; i++) {
19624 ResolveInfo resolveInfo = resolveInfos.get(i);
19626 if (resolveInfo.activityInfo != null && TextUtils.equals(
19627 resolveInfo.activityInfo.packageName, packageName)) {
19628 return new ComponentName(resolveInfo.activityInfo.packageName,
19629 resolveInfo.activityInfo.name);
19635 /** <b>must not hold {@link #mLock}</b> */
19636 private void updateDefaultHomeNotLocked(SparseBooleanArray userIds) {
19637 if (Thread.holdsLock(mLock)) {
19638 Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
19639 + " is holding mLock", new Throwable());
19641 for (int i = userIds.size() - 1; i >= 0; --i) {
19642 final int userId = userIds.keyAt(i);
19643 updateDefaultHomeNotLocked(userId);
19648 * <b>must not hold {@link #mLock}</b>
19650 * @return Whether the ACTION_PREFERRED_ACTIVITY_CHANGED broadcast has been scheduled.
19652 private boolean updateDefaultHomeNotLocked(int userId) {
19653 if (Thread.holdsLock(mLock)) {
19654 Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
19655 + " is holding mLock", new Throwable());
19657 if (!mSystemReady) {
19658 // We might get called before system is ready because of package changes etc, but
19659 // finding preferred activity depends on settings provider, so we ignore the update
19663 final Intent intent = getHomeIntent();
19664 final List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
19665 PackageManager.GET_META_DATA, userId);
19666 final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(
19667 intent, null, 0, resolveInfos, 0, true, false, false, userId);
19668 final String packageName = preferredResolveInfo != null
19669 && preferredResolveInfo.activityInfo != null
19670 ? preferredResolveInfo.activityInfo.packageName : null;
19671 final String currentPackageName = mPermissionManager.getDefaultHome(userId);
19672 if (TextUtils.equals(currentPackageName, packageName)) {
19675 final String[] callingPackages = getPackagesForUid(Binder.getCallingUid());
19676 if (callingPackages != null && ArrayUtils.contains(callingPackages,
19677 mRequiredPermissionControllerPackage)) {
19678 // PermissionController manages default home directly.
19681 mPermissionManager.setDefaultHome(packageName, userId, (successful) -> {
19683 postPreferredActivityChangedBroadcast(userId);
19690 public void setHomeActivity(ComponentName comp, int userId) {
19691 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19694 ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
19695 getHomeActivitiesAsUser(homeActivities, userId);
19697 boolean found = false;
19699 final int size = homeActivities.size();
19700 final ComponentName[] set = new ComponentName[size];
19701 for (int i = 0; i < size; i++) {
19702 final ResolveInfo candidate = homeActivities.get(i);
19703 final ActivityInfo info = candidate.activityInfo;
19704 final ComponentName activityName = new ComponentName(info.packageName, info.name);
19705 set[i] = activityName;
19706 if (!found && activityName.equals(comp)) {
19711 throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
19714 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
19715 set, comp, userId);
19718 private @Nullable String getSetupWizardPackageNameImpl() {
19719 final Intent intent = new Intent(Intent.ACTION_MAIN);
19720 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
19722 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19723 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19724 | MATCH_DISABLED_COMPONENTS,
19725 UserHandle.myUserId());
19726 if (matches.size() == 1) {
19727 return matches.get(0).getComponentInfo().packageName;
19729 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
19730 + ": matches=" + matches);
19735 private @Nullable String getStorageManagerPackageName() {
19736 final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
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 storage manager; found "
19746 + matches.size() + ": matches=" + matches);
19752 public String getDefaultTextClassifierPackageName() {
19753 return ensureSystemPackageName(
19754 mContext.getString(R.string.config_servicesExtensionPackage));
19758 public String getSystemTextClassifierPackageName() {
19759 return ensureSystemPackageName(
19760 mContext.getString(R.string.config_defaultTextClassifierPackage));
19764 public @Nullable String getAttentionServicePackageName() {
19765 final String flattenedComponentName =
19766 mContext.getString(R.string.config_defaultAttentionService);
19767 if (flattenedComponentName != null) {
19768 ComponentName componentName = ComponentName.unflattenFromString(flattenedComponentName);
19769 if (componentName != null && componentName.getPackageName() != null) {
19770 return ensureSystemPackageName(componentName.getPackageName());
19776 private @Nullable String getDocumenterPackageName() {
19777 final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
19778 intent.addCategory(Intent.CATEGORY_OPENABLE);
19779 intent.setType("*/*");
19780 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
19782 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, resolvedType,
19783 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19784 | MATCH_DISABLED_COMPONENTS,
19785 UserHandle.myUserId());
19786 if (matches.size() == 1) {
19787 return matches.get(0).getComponentInfo().packageName;
19789 Slog.e(TAG, "There should probably be exactly one documenter; found "
19790 + matches.size() + ": matches=" + matches);
19796 private String getDeviceConfiguratorPackageName() {
19797 return ensureSystemPackageName(mContext.getString(
19798 R.string.config_deviceConfiguratorPackageName));
19802 public String getWellbeingPackageName() {
19803 return ensureSystemPackageName(mContext.getString(R.string.config_defaultWellbeingPackage));
19807 public String getAppPredictionServicePackageName() {
19808 String flattenedAppPredictionServiceComponentName =
19809 mContext.getString(R.string.config_defaultAppPredictionService);
19810 if (flattenedAppPredictionServiceComponentName == null) {
19813 ComponentName appPredictionServiceComponentName =
19814 ComponentName.unflattenFromString(flattenedAppPredictionServiceComponentName);
19815 if (appPredictionServiceComponentName == null) {
19818 return ensureSystemPackageName(appPredictionServiceComponentName.getPackageName());
19821 private @NonNull String[] dropNonSystemPackages(@NonNull String[] pkgNames) {
19822 return emptyIfNull(filter(pkgNames, String[]::new, mIsSystemPackage), String.class);
19825 private Predicate<String> mIsSystemPackage = (pkgName) -> {
19826 if ("android".equals(pkgName)) {
19829 AndroidPackage pkg = mPackages.get(pkgName);
19830 return pkg != null && pkg.isSystem();
19834 public String getSystemCaptionsServicePackageName() {
19835 String flattenedSystemCaptionsServiceComponentName =
19836 mContext.getString(R.string.config_defaultSystemCaptionsService);
19838 if (TextUtils.isEmpty(flattenedSystemCaptionsServiceComponentName)) {
19842 ComponentName systemCaptionsServiceComponentName =
19843 ComponentName.unflattenFromString(flattenedSystemCaptionsServiceComponentName);
19844 if (systemCaptionsServiceComponentName == null) {
19847 return ensureSystemPackageName(systemCaptionsServiceComponentName.getPackageName());
19851 public String getSetupWizardPackageName() {
19852 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19853 throw new SecurityException("Non-system caller");
19855 return mPmInternal.getSetupWizardPackageName();
19858 public String getIncidentReportApproverPackageName() {
19859 return ensureSystemPackageName(mContext.getString(
19860 R.string.config_incidentReportApproverPackage));
19864 public String[] getTelephonyPackageNames() {
19865 String names = mContext.getString(R.string.config_telephonyPackages);
19866 String[] telephonyPackageNames = null;
19867 if (!TextUtils.isEmpty(names)) {
19868 telephonyPackageNames = names.trim().split(",");
19870 return ensureSystemPackageNames(telephonyPackageNames);
19874 public String getContentCaptureServicePackageName() {
19875 final String flattenedContentCaptureService =
19876 mContext.getString(R.string.config_defaultContentCaptureService);
19878 if (TextUtils.isEmpty(flattenedContentCaptureService)) {
19882 final ComponentName contentCaptureServiceComponentName =
19883 ComponentName.unflattenFromString(flattenedContentCaptureService);
19884 if (contentCaptureServiceComponentName == null) {
19887 return ensureSystemPackageName(contentCaptureServiceComponentName.getPackageName());
19891 private String getRetailDemoPackageName() {
19892 final String predefinedPkgName = mContext.getString(R.string.config_retailDemoPackage);
19893 final String predefinedSignature = mContext.getString(
19894 R.string.config_retailDemoPackageSignature);
19896 if (TextUtils.isEmpty(predefinedPkgName) || TextUtils.isEmpty(predefinedSignature)) {
19900 final AndroidPackage androidPkg = mPackages.get(predefinedPkgName);
19901 if (androidPkg != null) {
19902 final SigningDetails signingDetail = androidPkg.getSigningDetails();
19903 if (signingDetail != null && signingDetail.signatures != null) {
19905 final MessageDigest msgDigest = MessageDigest.getInstance("SHA-256");
19906 for (Signature signature : signingDetail.signatures) {
19907 if (TextUtils.equals(predefinedSignature,
19908 HexEncoding.encodeToString(msgDigest.digest(
19909 signature.toByteArray()), false))) {
19910 return predefinedPkgName;
19913 } catch (NoSuchAlgorithmException e) {
19916 "Unable to verify signatures as getting the retail demo package name",
19926 private String ensureSystemPackageName(@Nullable String packageName) {
19927 if (packageName == null) {
19930 long token = Binder.clearCallingIdentity();
19932 if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) {
19936 Binder.restoreCallingIdentity(token);
19938 return packageName;
19942 private String[] ensureSystemPackageNames(@Nullable String[] packageNames) {
19943 if (packageNames == null) {
19946 final int packageNamesLength = packageNames.length;
19947 for (int i = 0; i < packageNamesLength; i++) {
19948 packageNames[i] = ensureSystemPackageName(packageNames[i]);
19950 return ArrayUtils.filterNotNull(packageNames, String[]::new);
19954 public void setApplicationEnabledSetting(String appPackageName,
19955 int newState, int flags, int userId, String callingPackage) {
19956 if (!mUserManager.exists(userId)) return;
19957 if (callingPackage == null) {
19958 callingPackage = Integer.toString(Binder.getCallingUid());
19960 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
19964 public void setUpdateAvailable(String packageName, boolean updateAvailable) {
19965 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
19966 synchronized (mLock) {
19967 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
19968 if (pkgSetting != null) {
19969 pkgSetting.setUpdateAvailable(updateAvailable);
19975 public void setComponentEnabledSetting(ComponentName componentName,
19976 int newState, int flags, int userId) {
19977 if (!mUserManager.exists(userId)) return;
19978 setEnabledSetting(componentName.getPackageName(),
19979 componentName.getClassName(), newState, flags, userId, null);
19982 private void setEnabledSetting(final String packageName, String className, int newState,
19983 final int flags, int userId, String callingPackage) {
19984 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
19985 || newState == COMPONENT_ENABLED_STATE_ENABLED
19986 || newState == COMPONENT_ENABLED_STATE_DISABLED
19987 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
19988 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
19989 throw new IllegalArgumentException("Invalid new component state: "
19992 PackageSetting pkgSetting;
19993 final int callingUid = Binder.getCallingUid();
19994 final int permission;
19995 if (callingUid == Process.SYSTEM_UID) {
19996 permission = PackageManager.PERMISSION_GRANTED;
19998 permission = mContext.checkCallingOrSelfPermission(
19999 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20001 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20002 false /* requireFullPermission */, true /* checkShell */, "set enabled");
20003 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20004 boolean sendNow = false;
20005 boolean isApp = (className == null);
20006 final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
20007 String componentName = isApp ? packageName : className;
20008 ArrayList<String> components;
20011 synchronized (mLock) {
20012 pkgSetting = mSettings.mPackages.get(packageName);
20013 if (pkgSetting == null) {
20014 if (!isCallerInstantApp) {
20015 if (className == null) {
20016 throw new IllegalArgumentException("Unknown package: " + packageName);
20018 throw new IllegalArgumentException(
20019 "Unknown component: " + packageName + "/" + className);
20021 // throw SecurityException to prevent leaking package information
20022 throw new SecurityException(
20023 "Attempt to change component state; "
20024 + "pid=" + Binder.getCallingPid()
20025 + ", uid=" + callingUid
20026 + (className == null
20027 ? ", package=" + packageName
20028 : ", component=" + packageName + "/" + className));
20033 // Limit who can change which apps
20034 if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
20035 // Don't allow apps that don't have permission to modify other apps
20036 if (!allowedByPermission
20037 || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
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));
20046 // Don't allow changing protected packages.
20047 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20048 throw new SecurityException("Cannot disable a protected package: " + packageName);
20051 // Only allow apps with CHANGE_COMPONENT_ENABLED_STATE permission to change hidden
20052 // app details activity
20053 if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)
20054 && !allowedByPermission) {
20055 throw new SecurityException("Cannot disable a system-generated component");
20058 synchronized (mLock) {
20059 if (callingUid == Process.SHELL_UID
20060 && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20061 // Shell can only change whole packages between ENABLED and DISABLED_USER states
20062 // unless it is a test package.
20063 int oldState = pkgSetting.getEnabled(userId);
20064 if (className == null
20066 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20067 || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20068 || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20070 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20071 || newState == COMPONENT_ENABLED_STATE_DEFAULT
20072 || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20075 throw new SecurityException(
20076 "Shell cannot change component state for " + packageName + "/"
20077 + className + " to " + newState);
20081 if (className == null) {
20082 // We're dealing with an application/package level state change
20083 synchronized (mLock) {
20084 if (pkgSetting.getEnabled(userId) == newState) {
20089 // If we're enabling a system stub, there's a little more work to do.
20090 // Prior to enabling the package, we need to decompress the APK(s) to the
20091 // data partition and then replace the version on the system partition.
20092 final AndroidPackage deletedPkg = pkgSetting.pkg;
20093 final boolean isSystemStub = deletedPkg.isStub()
20094 && deletedPkg.isSystem();
20096 && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20097 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
20098 if (!enableCompressedPackage(deletedPkg, pkgSetting)) {
20102 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20103 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20104 // Don't care about who enables an app.
20105 callingPackage = null;
20107 synchronized (mLock) {
20108 pkgSetting.setEnabled(newState, userId, callingPackage);
20109 if (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20110 || newState == COMPONENT_ENABLED_STATE_DISABLED
20111 && pkgSetting.getPermissionsState().hasPermission(
20112 Manifest.permission.SUSPEND_APPS, userId)) {
20113 // This app should not generally be allowed to get disabled by the UI, but if it
20114 // ever does, we don't want to end up with some of the user's apps permanently
20116 unsuspendForSuspendingPackage(packageName, userId);
20117 removeAllDistractingPackageRestrictions(userId);
20121 synchronized (mLock) {
20122 // We're dealing with a component level state change
20123 // First, verify that this is a valid class name.
20124 AndroidPackage pkg = pkgSetting.pkg;
20125 if (pkg == null || !AndroidPackageUtils.hasComponentClassName(pkg, className)) {
20127 pkg.getTargetSdkVersion() >=
20128 Build.VERSION_CODES.JELLY_BEAN) {
20129 throw new IllegalArgumentException("Component class " + className
20130 + " does not exist in " + packageName);
20132 Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20133 + className + " does not exist in " + packageName);
20136 switch (newState) {
20137 case COMPONENT_ENABLED_STATE_ENABLED:
20138 if (!pkgSetting.enableComponentLPw(className, userId)) {
20142 case COMPONENT_ENABLED_STATE_DISABLED:
20143 if (!pkgSetting.disableComponentLPw(className, userId)) {
20147 case COMPONENT_ENABLED_STATE_DEFAULT:
20148 if (!pkgSetting.restoreComponentLPw(className, userId)) {
20153 Slog.e(TAG, "Invalid new component state: " + newState);
20158 synchronized (mLock) {
20159 if ((flags & PackageManager.SYNCHRONOUS) != 0) {
20160 flushPackageRestrictionsAsUserInternalLocked(userId);
20162 scheduleWritePackageRestrictionsLocked(userId);
20164 updateSequenceNumberLP(pkgSetting, new int[] { userId });
20165 final long callingId = Binder.clearCallingIdentity();
20167 updateInstantAppInstallerLocked(packageName);
20169 Binder.restoreCallingIdentity(callingId);
20171 components = mPendingBroadcasts.get(userId, packageName);
20172 final boolean newPackage = components == null;
20174 components = new ArrayList<>();
20176 if (!components.contains(componentName)) {
20177 components.add(componentName);
20179 if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20181 // Purge entry from pending broadcast list if another one exists already
20182 // since we are sending one right away.
20183 mPendingBroadcasts.remove(userId, packageName);
20186 mPendingBroadcasts.put(userId, packageName, components);
20188 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20189 // Schedule a message - if it has been a "reasonably long time" since the
20190 // service started, send the broadcast with a delay of one second to avoid
20191 // delayed reactions from the receiver, else keep the default ten second delay
20192 // to avoid extreme thrashing on service startup.
20193 final long broadcastDelay = SystemClock.uptimeMillis() > mServiceStartWithDelay
20195 : BROADCAST_DELAY_DURING_STARTUP;
20196 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, broadcastDelay);
20201 long callingId = Binder.clearCallingIdentity();
20204 int packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20205 sendPackageChangedBroadcast(packageName,
20206 (flags & PackageManager.DONT_KILL_APP) != 0, components, packageUid, null);
20209 Binder.restoreCallingIdentity(callingId);
20215 public void flushPackageRestrictionsAsUser(int userId) {
20216 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20219 if (!mUserManager.exists(userId)) {
20222 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20223 false /* checkShell */, "flushPackageRestrictions");
20224 synchronized (mLock) {
20225 flushPackageRestrictionsAsUserInternalLocked(userId);
20229 @GuardedBy("mLock")
20230 private void flushPackageRestrictionsAsUserInternalLocked(int userId) {
20231 // NOTE: this invokes synchronous disk access, so callers using this
20232 // method should consider running on a background thread
20233 mSettings.writePackageRestrictionsLPr(userId);
20234 mDirtyUsers.remove(userId);
20235 if (mDirtyUsers.isEmpty()) {
20236 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20240 private void sendPackageChangedBroadcast(String packageName,
20241 boolean dontKillApp, ArrayList<String> componentNames, int packageUid,
20244 Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20246 Bundle extras = new Bundle(4);
20247 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20248 String nameList[] = new String[componentNames.size()];
20249 componentNames.toArray(nameList);
20250 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
20251 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, dontKillApp);
20252 extras.putInt(Intent.EXTRA_UID, packageUid);
20253 if (reason != null) {
20254 extras.putString(Intent.EXTRA_REASON, reason);
20256 // If this is not reporting a change of the overall package, then only send it
20257 // to registered receivers. We don't want to launch a swath of apps for every
20258 // little component state change.
20259 final int flags = !componentNames.contains(packageName)
20260 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
20261 final int userId = UserHandle.getUserId(packageUid);
20262 final boolean isInstantApp = isInstantApp(packageName, userId);
20263 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
20264 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
20265 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null,
20266 userIds, instantUserIds);
20270 public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
20271 if (!mUserManager.exists(userId)) return;
20272 final int callingUid = Binder.getCallingUid();
20273 if (getInstantAppPackageName(callingUid) != null) {
20276 final int permission = mContext.checkCallingOrSelfPermission(
20277 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20278 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20279 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20280 true /* requireFullPermission */, true /* checkShell */, "stop package");
20282 synchronized (mLock) {
20283 final PackageSetting ps = mSettings.mPackages.get(packageName);
20284 if (!shouldFilterApplicationLocked(ps, callingUid, userId)
20285 && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
20286 allowedByPermission, callingUid, userId)) {
20287 scheduleWritePackageRestrictionsLocked(userId);
20293 public String getInstallerPackageName(String packageName) {
20294 final int callingUid = Binder.getCallingUid();
20295 synchronized (mLock) {
20296 final InstallSource installSource = getInstallSourceLocked(packageName, callingUid);
20297 if (installSource == null) {
20298 throw new IllegalArgumentException("Unknown package: " + packageName);
20300 String installerPackageName = installSource.installerPackageName;
20301 if (installerPackageName != null) {
20302 final PackageSetting ps = mSettings.mPackages.get(installerPackageName);
20303 if (ps == null || shouldFilterApplicationLocked(ps, callingUid,
20304 UserHandle.getUserId(callingUid))) {
20305 installerPackageName = null;
20308 return installerPackageName;
20314 public InstallSourceInfo getInstallSourceInfo(String packageName) {
20315 final int callingUid = Binder.getCallingUid();
20316 final int userId = UserHandle.getUserId(callingUid);
20318 String installerPackageName;
20319 String initiatingPackageName;
20320 String originatingPackageName;
20322 final InstallSource installSource;
20323 synchronized (mLock) {
20324 installSource = getInstallSourceLocked(packageName, callingUid);
20325 if (installSource == null) {
20329 installerPackageName = installSource.installerPackageName;
20330 if (installerPackageName != null) {
20331 final PackageSetting ps = mSettings.mPackages.get(installerPackageName);
20332 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
20333 installerPackageName = null;
20337 if (installSource.isInitiatingPackageUninstalled) {
20338 // We can't check visibility in the usual way, since the initiating package is no
20339 // longer present. So we apply simpler rules to whether to expose the info:
20340 // 1. Instant apps can't see it.
20341 // 2. Otherwise only the installed app itself can see it.
20342 final boolean isInstantApp = getInstantAppPackageName(callingUid) != null;
20343 if (!isInstantApp && isCallerSameApp(packageName, callingUid)) {
20344 initiatingPackageName = installSource.initiatingPackageName;
20346 initiatingPackageName = null;
20349 // All installSource strings are interned, so == is ok here
20350 if (installSource.initiatingPackageName == installSource.installerPackageName) {
20351 // The installer and initiator will often be the same, and when they are
20352 // we can skip doing the same check again.
20353 initiatingPackageName = installerPackageName;
20355 initiatingPackageName = installSource.initiatingPackageName;
20356 final PackageSetting ps = mSettings.mPackages.get(initiatingPackageName);
20357 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
20358 initiatingPackageName = null;
20363 originatingPackageName = installSource.originatingPackageName;
20364 if (originatingPackageName != null) {
20365 final PackageSetting ps = mSettings.mPackages.get(originatingPackageName);
20366 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
20367 originatingPackageName = null;
20372 // Remaining work can safely be done outside the lock. (Note that installSource is
20373 // immutable so it's ok to carry on reading from it.)
20375 if (originatingPackageName != null && mContext.checkCallingOrSelfPermission(
20376 Manifest.permission.INSTALL_PACKAGES) != PackageManager.PERMISSION_GRANTED) {
20377 originatingPackageName = null;
20380 // If you can see the initiatingPackageName, and we have valid signing info for it,
20381 // then we let you see that too.
20382 final SigningInfo initiatingPackageSigningInfo;
20383 final PackageSignatures signatures = installSource.initiatingPackageSignatures;
20384 if (initiatingPackageName != null && signatures != null
20385 && signatures.mSigningDetails != SigningDetails.UNKNOWN) {
20386 initiatingPackageSigningInfo = new SigningInfo(signatures.mSigningDetails);
20388 initiatingPackageSigningInfo = null;
20391 return new InstallSourceInfo(initiatingPackageName, initiatingPackageSigningInfo,
20392 originatingPackageName, installerPackageName);
20395 @GuardedBy("mLock")
20397 private InstallSource getInstallSourceLocked(String packageName, int callingUid) {
20398 final PackageSetting ps = mSettings.mPackages.get(packageName);
20400 // Installer info for Apex is not stored in PackageManager
20401 if (ps == null && mApexManager.isApexPackage(packageName)) {
20402 return InstallSource.EMPTY;
20405 if (ps == null || shouldFilterApplicationLocked(ps, callingUid,
20406 UserHandle.getUserId(callingUid))) {
20410 return ps.installSource;
20413 public boolean isOrphaned(String packageName) {
20415 synchronized (mLock) {
20416 if (!mPackages.containsKey(packageName)) {
20419 return mSettings.isOrphaned(packageName);
20424 public int getApplicationEnabledSetting(String packageName, int userId) {
20425 if (!mUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20426 int callingUid = Binder.getCallingUid();
20427 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20428 false /* requireFullPermission */, false /* checkShell */, "get enabled");
20430 synchronized (mLock) {
20431 if (shouldFilterApplicationLocked(
20432 mSettings.getPackageLPr(packageName), callingUid, userId)) {
20433 return COMPONENT_ENABLED_STATE_DISABLED;
20435 return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20440 public int getComponentEnabledSetting(@NonNull ComponentName component, int userId) {
20441 if (component == null) return COMPONENT_ENABLED_STATE_DEFAULT;
20442 if (!mUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20443 int callingUid = Binder.getCallingUid();
20444 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20445 false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
20446 synchronized (mLock) {
20447 if (shouldFilterApplicationLocked(
20448 mSettings.getPackageLPr(component.getPackageName()), callingUid,
20449 component, TYPE_UNKNOWN, userId)) {
20450 return COMPONENT_ENABLED_STATE_DISABLED;
20452 return mSettings.getComponentEnabledSettingLPr(component, userId);
20457 public void enterSafeMode() {
20458 enforceSystemOrRoot("Only the system can request entering safe mode");
20460 if (!mSystemReady) {
20466 public void systemReady() {
20467 enforceSystemOrRoot("Only the system can claim the system is ready");
20469 mSystemReady = true;
20470 final ContentResolver resolver = mContext.getContentResolver();
20471 ContentObserver co = new ContentObserver(mHandler) {
20473 public void onChange(boolean selfChange) {
20474 final boolean ephemeralFeatureDisabled =
20475 Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0;
20476 for (int userId : UserManagerService.getInstance().getUserIds()) {
20477 final boolean instantAppsDisabledForUser =
20478 ephemeralFeatureDisabled || Secure.getIntForUser(resolver,
20479 Secure.INSTANT_APPS_ENABLED, 1, userId) == 0;
20480 mWebInstantAppsDisabled.put(userId, instantAppsDisabledForUser);
20484 mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20485 .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20486 false, co, UserHandle.USER_ALL);
20487 mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure
20488 .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL);
20491 mAppsFilter.onSystemReady();
20493 // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20494 // disabled after already being started.
20495 CarrierAppUtils.disableCarrierAppsUntilPrivileged(
20496 mContext.getOpPackageName(), UserHandle.USER_SYSTEM, mContext);
20498 disableSkuSpecificApps();
20500 // Read the compatibilty setting when the system is ready.
20501 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20502 mContext.getContentResolver(),
20503 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20504 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20506 if (DEBUG_SETTINGS) {
20507 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20510 synchronized (mLock) {
20511 // Verify that all of the preferred activity components actually
20512 // exist. It is possible for applications to be updated and at
20513 // that point remove a previously declared activity component that
20514 // had been set as a preferred activity. We try to clean this up
20515 // the next time we encounter that preferred activity, but it is
20516 // possible for the user flow to never be able to return to that
20517 // situation so here we do a sanity check to make sure we haven't
20518 // left any junk around.
20519 ArrayList<PreferredActivity> removed = new ArrayList<>();
20520 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20521 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20523 for (PreferredActivity pa : pir.filterSet()) {
20524 if (!mComponentResolver.isActivityDefined(pa.mPref.mComponent)) {
20528 if (removed.size() > 0) {
20529 for (int r=0; r<removed.size(); r++) {
20530 PreferredActivity pa = removed.get(r);
20531 Slog.w(TAG, "Removing dangling preferred activity: "
20532 + pa.mPref.mComponent);
20533 pir.removeFilter(pa);
20535 mSettings.writePackageRestrictionsLPr(
20536 mSettings.mPreferredActivities.keyAt(i));
20541 mUserManager.systemReady();
20543 // Now that we've scanned all packages, and granted any default
20544 // permissions, ensure permissions are updated. Beware of dragons if you
20545 // try optimizing this.
20546 synchronized (mLock) {
20547 mPermissionManager.updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, false);
20549 final PermissionPolicyInternal permissionPolicyInternal =
20550 mInjector.getPermissionPolicyInternal();
20551 permissionPolicyInternal.setOnInitializedCallback(userId -> {
20552 // The SDK updated case is already handled when we run during the ctor.
20553 synchronized (mLock) {
20554 mPermissionManager.updateAllPermissions(
20555 StorageManager.UUID_PRIVATE_INTERNAL, false);
20560 // Watch for external volumes that come and go over time
20561 final StorageManager storage = mInjector.getStorageManager();
20562 storage.registerListener(mStorageListener);
20564 mInstallerService.systemReady();
20565 mApexManager.systemReady(mContext);
20566 mPackageDexOptimizer.systemReady();
20568 mInjector.getStorageManagerInternal().addExternalStoragePolicy(
20569 new StorageManagerInternal.ExternalStorageMountPolicy() {
20571 public int getMountMode(int uid, String packageName) {
20572 if (Process.isIsolated(uid)) {
20573 return Zygote.MOUNT_EXTERNAL_NONE;
20575 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20576 return Zygote.MOUNT_EXTERNAL_DEFAULT;
20578 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20579 return Zygote.MOUNT_EXTERNAL_READ;
20581 return Zygote.MOUNT_EXTERNAL_WRITE;
20585 public boolean hasExternalStorage(int uid, String packageName) {
20590 // Now that we're mostly running, clean up stale users and apps
20591 mUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20592 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20594 mPermissionManager.systemReady();
20596 if (mInstantAppResolverConnection != null) {
20597 mContext.registerReceiver(new BroadcastReceiver() {
20599 public void onReceive(Context context, Intent intent) {
20600 mInstantAppResolverConnection.optimisticBind();
20601 mContext.unregisterReceiver(this);
20603 }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
20606 IntentFilter overlayFilter = new IntentFilter(Intent.ACTION_OVERLAY_CHANGED);
20607 overlayFilter.addDataScheme("package");
20608 mContext.registerReceiver(new BroadcastReceiver() {
20610 public void onReceive(Context context, Intent intent) {
20611 if (intent == null) {
20614 Uri data = intent.getData();
20615 if (data == null) {
20618 String packageName = data.getSchemeSpecificPart();
20619 if (packageName == null) {
20622 AndroidPackage pkg = mPackages.get(packageName);
20626 sendPackageChangedBroadcast(pkg.getPackageName(),
20627 true /* dontKillApp */,
20628 new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
20630 Intent.ACTION_OVERLAY_CHANGED);
20634 mModuleInfoProvider.systemReady();
20636 // Installer service might attempt to install some packages that have been staged for
20637 // installation on reboot. Make sure this is the last component to be call since the
20638 // installation might require other components to be ready.
20639 mInstallerService.restoreAndApplyStagedSessionIfNeeded();
20642 public void waitForAppDataPrepared() {
20643 if (mPrepareAppDataFuture == null) {
20646 ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20647 mPrepareAppDataFuture = null;
20651 public boolean isSafeMode() {
20652 // allow instant applications
20657 public boolean hasSystemUidErrors() {
20658 // allow instant applications
20659 return mHasSystemUidErrors;
20662 static String arrayToString(int[] array) {
20663 StringBuilder stringBuilder = new StringBuilder(128);
20664 stringBuilder.append('[');
20665 if (array != null) {
20666 for (int i=0; i<array.length; i++) {
20667 if (i > 0) stringBuilder.append(", ");
20668 stringBuilder.append(array[i]);
20671 stringBuilder.append(']');
20672 return stringBuilder.toString();
20676 public void onShellCommand(FileDescriptor in, FileDescriptor out,
20677 FileDescriptor err, String[] args, ShellCallback callback,
20678 ResultReceiver resultReceiver) {
20679 (new PackageManagerShellCommand(this, mPermissionManagerService)).exec(
20680 this, in, out, err, args, callback, resultReceiver);
20683 @SuppressWarnings("resource")
20685 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20686 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
20688 DumpState dumpState = new DumpState();
20689 boolean fullPreferred = false;
20690 boolean checkin = false;
20692 String packageName = null;
20693 ArraySet<String> permissionNames = null;
20696 while (opti < args.length) {
20697 String opt = args[opti];
20698 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
20703 if ("-a".equals(opt)) {
20704 // Right now we only know how to print all.
20705 } else if ("-h".equals(opt)) {
20706 pw.println("Package manager dump options:");
20707 pw.println(" [-h] [-f] [--checkin] [--all-components] [cmd] ...");
20708 pw.println(" --checkin: dump for a checkin");
20709 pw.println(" -f: print details of intent filters");
20710 pw.println(" -h: print this help");
20711 pw.println(" --all-components: include all component names in package dump");
20712 pw.println(" cmd may be one of:");
20713 pw.println(" apex: list active APEXes and APEX session state");
20714 pw.println(" l[ibraries]: list known shared libraries");
20715 pw.println(" f[eatures]: list device features");
20716 pw.println(" k[eysets]: print known keysets");
20717 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
20718 pw.println(" perm[issions]: dump permissions");
20719 pw.println(" permission [name ...]: dump declaration and use of given permission");
20720 pw.println(" pref[erred]: print preferred package settings");
20721 pw.println(" preferred-xml [--full]: print preferred package settings as xml");
20722 pw.println(" prov[iders]: dump content providers");
20723 pw.println(" p[ackages]: dump installed packages");
20724 pw.println(" q[ueries]: dump app queryability calculations");
20725 pw.println(" s[hared-users]: dump shared user IDs");
20726 pw.println(" m[essages]: print collected runtime messages");
20727 pw.println(" v[erifiers]: print package verifier info");
20728 pw.println(" d[omain-preferred-apps]: print domains preferred apps");
20729 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
20730 pw.println(" version: print database version info");
20731 pw.println(" write: write current settings now");
20732 pw.println(" installs: details about install sessions");
20733 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?");
20734 pw.println(" dexopt: dump dexopt state");
20735 pw.println(" compiler-stats: dump compiler statistics");
20736 pw.println(" service-permissions: dump permissions required by services");
20737 pw.println(" <package.name>: info about given package");
20739 } else if ("--checkin".equals(opt)) {
20741 } else if ("--all-components".equals(opt)) {
20742 dumpState.setOptionEnabled(DumpState.OPTION_DUMP_ALL_COMPONENTS);
20743 } else if ("-f".equals(opt)) {
20744 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20745 } else if ("--proto".equals(opt)) {
20749 pw.println("Unknown argument: " + opt + "; use -h for help");
20753 // Is the caller requesting to dump a particular piece of data?
20754 if (opti < args.length) {
20755 String cmd = args[opti];
20757 // Is this a package name?
20758 if ("android".equals(cmd) || cmd.contains(".")) {
20760 // When dumping a single package, we always dump all of its
20761 // filter information since the amount of data will be reasonable.
20762 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20763 } else if ("check-permission".equals(cmd)) {
20764 if (opti >= args.length) {
20765 pw.println("Error: check-permission missing permission argument");
20768 String perm = args[opti];
20770 if (opti >= args.length) {
20771 pw.println("Error: check-permission missing package argument");
20775 String pkg = args[opti];
20777 int user = UserHandle.getUserId(Binder.getCallingUid());
20778 if (opti < args.length) {
20780 user = Integer.parseInt(args[opti]);
20781 } catch (NumberFormatException e) {
20782 pw.println("Error: check-permission user argument is not a number: "
20788 // Normalize package name to handle renamed packages and static libs
20789 pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
20791 pw.println(checkPermission(perm, pkg, user));
20793 } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
20794 dumpState.setDump(DumpState.DUMP_LIBS);
20795 } else if ("f".equals(cmd) || "features".equals(cmd)) {
20796 dumpState.setDump(DumpState.DUMP_FEATURES);
20797 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
20798 if (opti >= args.length) {
20799 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
20800 | DumpState.DUMP_SERVICE_RESOLVERS
20801 | DumpState.DUMP_RECEIVER_RESOLVERS
20802 | DumpState.DUMP_CONTENT_RESOLVERS);
20804 while (opti < args.length) {
20805 String name = args[opti];
20806 if ("a".equals(name) || "activity".equals(name)) {
20807 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
20808 } else if ("s".equals(name) || "service".equals(name)) {
20809 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
20810 } else if ("r".equals(name) || "receiver".equals(name)) {
20811 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
20812 } else if ("c".equals(name) || "content".equals(name)) {
20813 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
20815 pw.println("Error: unknown resolver table type: " + name);
20821 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
20822 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
20823 } else if ("permission".equals(cmd)) {
20824 if (opti >= args.length) {
20825 pw.println("Error: permission requires permission name");
20828 permissionNames = new ArraySet<>();
20829 while (opti < args.length) {
20830 permissionNames.add(args[opti]);
20833 dumpState.setDump(DumpState.DUMP_PERMISSIONS
20834 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
20835 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
20836 dumpState.setDump(DumpState.DUMP_PREFERRED);
20837 } else if ("preferred-xml".equals(cmd)) {
20838 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
20839 if (opti < args.length && "--full".equals(args[opti])) {
20840 fullPreferred = true;
20843 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
20844 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
20845 } else if ("p".equals(cmd) || "packages".equals(cmd)) {
20846 dumpState.setDump(DumpState.DUMP_PACKAGES);
20847 } else if ("q".equals(cmd) || "queries".equals(cmd)) {
20848 dumpState.setDump(DumpState.DUMP_QUERIES);
20849 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
20850 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
20851 if (opti < args.length && "noperm".equals(args[opti])) {
20852 dumpState.setOptionEnabled(DumpState.OPTION_SKIP_PERMISSIONS);
20854 } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
20855 dumpState.setDump(DumpState.DUMP_PROVIDERS);
20856 } else if ("m".equals(cmd) || "messages".equals(cmd)) {
20857 dumpState.setDump(DumpState.DUMP_MESSAGES);
20858 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
20859 dumpState.setDump(DumpState.DUMP_VERIFIERS);
20860 } else if ("i".equals(cmd) || "ifv".equals(cmd)
20861 || "intent-filter-verifiers".equals(cmd)) {
20862 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
20863 } else if ("version".equals(cmd)) {
20864 dumpState.setDump(DumpState.DUMP_VERSION);
20865 } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
20866 dumpState.setDump(DumpState.DUMP_KEYSETS);
20867 } else if ("installs".equals(cmd)) {
20868 dumpState.setDump(DumpState.DUMP_INSTALLS);
20869 } else if ("frozen".equals(cmd)) {
20870 dumpState.setDump(DumpState.DUMP_FROZEN);
20871 } else if ("volumes".equals(cmd)) {
20872 dumpState.setDump(DumpState.DUMP_VOLUMES);
20873 } else if ("dexopt".equals(cmd)) {
20874 dumpState.setDump(DumpState.DUMP_DEXOPT);
20875 } else if ("compiler-stats".equals(cmd)) {
20876 dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
20877 } else if ("changes".equals(cmd)) {
20878 dumpState.setDump(DumpState.DUMP_CHANGES);
20879 } else if ("service-permissions".equals(cmd)) {
20880 dumpState.setDump(DumpState.DUMP_SERVICE_PERMISSIONS);
20881 } else if ("write".equals(cmd)) {
20882 synchronized (mLock) {
20883 mSettings.writeLPr();
20884 pw.println("Settings written.");
20891 pw.println("vers,1");
20895 synchronized (mLock) {
20896 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
20898 if (dumpState.onTitlePrinted())
20900 pw.println("Database versions:");
20901 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " "));
20905 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
20907 if (dumpState.onTitlePrinted())
20909 pw.println("Verifiers:");
20910 pw.print(" Required: ");
20911 pw.print(mRequiredVerifierPackage);
20912 pw.print(" (uid=");
20913 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20914 UserHandle.USER_SYSTEM));
20916 } else if (mRequiredVerifierPackage != null) {
20917 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
20919 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20920 UserHandle.USER_SYSTEM));
20924 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
20925 packageName == null) {
20926 if (mIntentFilterVerifierComponent != null) {
20927 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
20929 if (dumpState.onTitlePrinted())
20931 pw.println("Intent Filter Verifier:");
20932 pw.print(" Using: ");
20933 pw.print(verifierPackageName);
20934 pw.print(" (uid=");
20935 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20936 UserHandle.USER_SYSTEM));
20938 } else if (verifierPackageName != null) {
20939 pw.print("ifv,"); pw.print(verifierPackageName);
20941 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20942 UserHandle.USER_SYSTEM));
20946 pw.println("No Intent Filter Verifier available!");
20950 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
20951 boolean printedHeader = false;
20952 final Iterator<String> it = mSharedLibraries.keySet().iterator();
20953 while (it.hasNext()) {
20954 String libName = it.next();
20955 LongSparseArray<SharedLibraryInfo> versionedLib
20956 = mSharedLibraries.get(libName);
20957 if (versionedLib == null) {
20960 final int versionCount = versionedLib.size();
20961 for (int i = 0; i < versionCount; i++) {
20962 SharedLibraryInfo libraryInfo = versionedLib.valueAt(i);
20964 if (!printedHeader) {
20965 if (dumpState.onTitlePrinted())
20967 pw.println("Libraries:");
20968 printedHeader = true;
20974 pw.print(libraryInfo.getName());
20975 if (libraryInfo.isStatic()) {
20976 pw.print(" version=" + libraryInfo.getLongVersion());
20981 if (libraryInfo.getPath() != null) {
20982 pw.print(" (jar) ");
20983 pw.print(libraryInfo.getPath());
20985 pw.print(" (apk) ");
20986 pw.print(libraryInfo.getPackageName());
20993 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
20994 if (dumpState.onTitlePrinted())
20997 pw.println("Features:");
21000 synchronized (mAvailableFeatures) {
21001 for (FeatureInfo feat : mAvailableFeatures.values()) {
21004 pw.print(feat.name);
21006 pw.println(feat.version);
21009 pw.print(feat.name);
21010 if (feat.version > 0) {
21011 pw.print(" version=");
21012 pw.print(feat.version);
21020 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
21021 mComponentResolver.dumpActivityResolvers(pw, dumpState, packageName);
21023 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
21024 mComponentResolver.dumpReceiverResolvers(pw, dumpState, packageName);
21026 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
21027 mComponentResolver.dumpServiceResolvers(pw, dumpState, packageName);
21029 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
21030 mComponentResolver.dumpProviderResolvers(pw, dumpState, packageName);
21033 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
21034 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21035 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21036 int user = mSettings.mPreferredActivities.keyAt(i);
21038 dumpState.getTitlePrinted()
21039 ? "\nPreferred Activities User " + user + ":"
21040 : "Preferred Activities User " + user + ":", " ",
21041 packageName, true, false)) {
21042 dumpState.setTitlePrinted(true);
21047 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
21049 FileOutputStream fout = new FileOutputStream(fd);
21050 BufferedOutputStream str = new BufferedOutputStream(fout);
21051 XmlSerializer serializer = new FastXmlSerializer();
21053 serializer.setOutput(str, StandardCharsets.UTF_8.name());
21054 serializer.startDocument(null, true);
21055 serializer.setFeature(
21056 "http://xmlpull.org/v1/doc/features.html#indent-output", true);
21057 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
21058 serializer.endDocument();
21059 serializer.flush();
21060 } catch (IllegalArgumentException e) {
21061 pw.println("Failed writing: " + e);
21062 } catch (IllegalStateException e) {
21063 pw.println("Failed writing: " + e);
21064 } catch (IOException e) {
21065 pw.println("Failed writing: " + e);
21070 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
21071 && packageName == null) {
21073 int count = mSettings.mPackages.size();
21075 pw.println("No applications!");
21078 final String prefix = " ";
21079 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
21080 if (allPackageSettings.size() == 0) {
21081 pw.println("No domain preferred apps!");
21084 pw.println("App verification status:");
21087 for (PackageSetting ps : allPackageSettings) {
21088 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
21089 if (ivi == null || ivi.getPackageName() == null) continue;
21090 pw.println(prefix + "Package: " + ivi.getPackageName());
21091 pw.println(prefix + "Domains: " + ivi.getDomainsString());
21092 pw.println(prefix + "Status: " + ivi.getStatusString());
21097 pw.println(prefix + "No app verification established.");
21100 for (int userId : mUserManager.getUserIds()) {
21101 pw.println("App linkages for user " + userId + ":");
21104 for (PackageSetting ps : allPackageSettings) {
21105 final long status = ps.getDomainVerificationStatusForUser(userId);
21106 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
21107 && !DEBUG_DOMAIN_VERIFICATION) {
21110 pw.println(prefix + "Package: " + ps.name);
21111 pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
21112 String statusStr = IntentFilterVerificationInfo.
21113 getStatusStringFromValue(status);
21114 pw.println(prefix + "Status: " + statusStr);
21119 pw.println(prefix + "No configured app linkages.");
21127 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21128 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21131 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21132 mComponentResolver.dumpContentProviders(pw, dumpState, packageName);
21135 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21136 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21139 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21140 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21143 if (dumpState.isDumping(DumpState.DUMP_QUERIES)) {
21144 final PackageSetting setting = mSettings.getPackageLPr(packageName);
21145 Integer filteringAppId = setting == null ? null : setting.appId;
21146 mAppsFilter.dumpQueries(
21147 pw, this, filteringAppId, dumpState,
21148 mUserManager.getUserIds());
21151 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21152 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21155 if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
21156 if (dumpState.onTitlePrinted()) pw.println();
21157 pw.println("Package Changes:");
21158 pw.print(" Sequence number="); pw.println(mChangedPackagesSequenceNumber);
21159 final int K = mChangedPackages.size();
21160 for (int i = 0; i < K; i++) {
21161 final SparseArray<String> changes = mChangedPackages.valueAt(i);
21162 pw.print(" User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
21163 final int N = changes.size();
21165 pw.print(" "); pw.println("No packages changed");
21167 for (int j = 0; j < N; j++) {
21168 final String pkgName = changes.valueAt(j);
21169 final int sequenceNumber = changes.keyAt(j);
21172 pw.print(sequenceNumber);
21173 pw.print(", package=");
21174 pw.println(pkgName);
21180 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21181 // XXX should handle packageName != null by dumping only install data that
21182 // the given package is involved with.
21183 if (dumpState.onTitlePrinted()) pw.println();
21185 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
21187 ipw.println("Frozen packages:");
21188 ipw.increaseIndent();
21189 if (mFrozenPackages.size() == 0) {
21190 ipw.println("(none)");
21192 for (int i = 0; i < mFrozenPackages.size(); i++) {
21193 ipw.println(mFrozenPackages.valueAt(i));
21196 ipw.decreaseIndent();
21199 if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
21200 if (dumpState.onTitlePrinted()) pw.println();
21202 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
21204 ipw.println("Loaded volumes:");
21205 ipw.increaseIndent();
21206 if (mLoadedVolumes.size() == 0) {
21207 ipw.println("(none)");
21209 for (int i = 0; i < mLoadedVolumes.size(); i++) {
21210 ipw.println(mLoadedVolumes.valueAt(i));
21213 ipw.decreaseIndent();
21216 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
21217 && packageName == null) {
21218 mComponentResolver.dumpServicePermissions(pw, dumpState);
21221 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21222 if (dumpState.onTitlePrinted()) pw.println();
21223 dumpDexoptStateLPr(pw, packageName);
21226 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21227 if (dumpState.onTitlePrinted()) pw.println();
21228 dumpCompilerStatsLPr(pw, packageName);
21231 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21232 if (dumpState.onTitlePrinted()) pw.println();
21233 mSettings.dumpReadMessagesLPr(pw, dumpState);
21236 pw.println("Package warning messages:");
21237 dumpCriticalInfo(pw, null);
21240 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21241 dumpCriticalInfo(pw, "msg,");
21245 // PackageInstaller should be called outside of mPackages lock
21246 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21247 // XXX should handle packageName != null by dumping only install data that
21248 // the given package is involved with.
21249 if (dumpState.onTitlePrinted()) pw.println();
21250 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120));
21253 if (!checkin && dumpState.isDumping(DumpState.DUMP_APEX)) {
21254 mApexManager.dump(pw, packageName);
21258 //TODO: b/111402650
21259 private void disableSkuSpecificApps() {
21260 String apkList[] = mContext.getResources().getStringArray(
21261 R.array.config_disableApksUnlessMatchedSku_apk_list);
21262 String skuArray[] = mContext.getResources().getStringArray(
21263 R.array.config_disableApkUnlessMatchedSku_skus_list);
21264 if (ArrayUtils.isEmpty(apkList)) {
21267 String sku = SystemProperties.get("ro.boot.hardware.sku");
21268 if (!TextUtils.isEmpty(sku) && ArrayUtils.contains(skuArray, sku)) {
21271 for (String packageName : apkList) {
21272 setSystemAppHiddenUntilInstalled(packageName, true);
21273 for (UserInfo user : mUserManager.getUsers(false)) {
21274 setSystemAppInstallState(packageName, false, user.id);
21279 private void dumpProto(FileDescriptor fd) {
21280 final ProtoOutputStream proto = new ProtoOutputStream(fd);
21282 synchronized (mLock) {
21283 final long requiredVerifierPackageToken =
21284 proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21285 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21287 PackageServiceDumpProto.PackageShortProto.UID,
21289 mRequiredVerifierPackage,
21290 MATCH_DEBUG_TRIAGED_MISSING,
21291 UserHandle.USER_SYSTEM));
21292 proto.end(requiredVerifierPackageToken);
21294 if (mIntentFilterVerifierComponent != null) {
21295 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21296 final long verifierPackageToken =
21297 proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21298 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21300 PackageServiceDumpProto.PackageShortProto.UID,
21302 verifierPackageName,
21303 MATCH_DEBUG_TRIAGED_MISSING,
21304 UserHandle.USER_SYSTEM));
21305 proto.end(verifierPackageToken);
21308 dumpSharedLibrariesProto(proto);
21309 dumpFeaturesProto(proto);
21310 mSettings.dumpPackagesProto(proto);
21311 mSettings.dumpSharedUsersProto(proto);
21312 dumpCriticalInfo(proto);
21317 private void dumpFeaturesProto(ProtoOutputStream proto) {
21318 synchronized (mAvailableFeatures) {
21319 final int count = mAvailableFeatures.size();
21320 for (int i = 0; i < count; i++) {
21321 mAvailableFeatures.valueAt(i).dumpDebug(proto, PackageServiceDumpProto.FEATURES);
21326 private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21327 final int count = mSharedLibraries.size();
21328 for (int i = 0; i < count; i++) {
21329 final String libName = mSharedLibraries.keyAt(i);
21330 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(libName);
21331 if (versionedLib == null) {
21334 final int versionCount = versionedLib.size();
21335 for (int j = 0; j < versionCount; j++) {
21336 final SharedLibraryInfo libraryInfo = versionedLib.valueAt(j);
21337 final long sharedLibraryToken =
21338 proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21339 proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libraryInfo.getName());
21340 final boolean isJar = (libraryInfo.getPath() != null);
21341 proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21343 proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH,
21344 libraryInfo.getPath());
21346 proto.write(PackageServiceDumpProto.SharedLibraryProto.APK,
21347 libraryInfo.getPackageName());
21349 proto.end(sharedLibraryToken);
21354 @GuardedBy("mLock")
21355 @SuppressWarnings("resource")
21356 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21357 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
21359 ipw.println("Dexopt state:");
21360 ipw.increaseIndent();
21361 Collection<PackageSetting> pkgSettings;
21362 if (packageName != null) {
21363 PackageSetting targetPkgSetting = mSettings.mPackages.get(packageName);
21364 if (targetPkgSetting != null) {
21365 pkgSettings = Collections.singletonList(targetPkgSetting);
21367 ipw.println("Unable to find package: " + packageName);
21371 pkgSettings = mSettings.mPackages.values();
21374 for (PackageSetting pkgSetting : pkgSettings) {
21375 if (pkgSetting.pkg == null) {
21378 ipw.println("[" + pkgSetting.name + "]");
21379 ipw.increaseIndent();
21380 mPackageDexOptimizer.dumpDexoptState(ipw, pkgSetting.pkg, pkgSetting,
21381 mDexManager.getPackageUseInfoOrDefault(pkgSetting.pkg.getPackageName()));
21382 ipw.decreaseIndent();
21386 @GuardedBy("mLock")
21387 @SuppressWarnings("resource")
21388 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
21389 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
21391 ipw.println("Compiler stats:");
21392 ipw.increaseIndent();
21393 Collection<AndroidPackage> packages;
21394 if (packageName != null) {
21395 AndroidPackage targetPackage = mPackages.get(packageName);
21396 if (targetPackage != null) {
21397 packages = Collections.singletonList(targetPackage);
21399 ipw.println("Unable to find package: " + packageName);
21403 packages = mPackages.values();
21406 for (AndroidPackage pkg : packages) {
21407 ipw.println("[" + pkg.getPackageName() + "]");
21408 ipw.increaseIndent();
21410 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.getPackageName());
21411 if (stats == null) {
21412 ipw.println("(No recorded stats)");
21416 ipw.decreaseIndent();
21420 private String dumpDomainString(String packageName) {
21421 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21423 List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21425 ArraySet<String> result = new ArraySet<>();
21426 if (iviList.size() > 0) {
21427 for (IntentFilterVerificationInfo ivi : iviList) {
21428 result.addAll(ivi.getDomains());
21431 if (filters != null && filters.size() > 0) {
21432 for (IntentFilter filter : filters) {
21433 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21434 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21435 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21436 result.addAll(filter.getHostsList());
21441 StringBuilder sb = new StringBuilder(result.size() * 16);
21442 for (String domain : result) {
21443 if (sb.length() > 0) sb.append(" ");
21446 return sb.toString();
21449 // ------- apps on sdcard specific code -------
21450 static final boolean DEBUG_SD_INSTALL = false;
21452 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21454 private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21456 private boolean mMediaMounted = false;
21458 static String getEncryptKey() {
21460 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21461 SD_ENCRYPTION_KEYSTORE_NAME);
21462 if (sdEncKey == null) {
21463 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21464 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21465 if (sdEncKey == null) {
21466 Slog.e(TAG, "Failed to create encryption keys");
21471 } catch (NoSuchAlgorithmException nsae) {
21472 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21474 } catch (IOException ioe) {
21475 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21480 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21481 ArrayList<AndroidPackage> packages, IIntentReceiver finishedReceiver) {
21482 final int size = packages.size();
21483 final String[] packageNames = new String[size];
21484 final int[] packageUids = new int[size];
21485 for (int i = 0; i < size; i++) {
21486 final AndroidPackage pkg = packages.get(i);
21487 packageNames[i] = pkg.getPackageName();
21488 packageUids[i] = pkg.getUid();
21490 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
21494 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21495 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21496 sendResourcesChangedBroadcast(mediaStatus, replacing,
21497 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
21500 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21501 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21502 int size = pkgList.length;
21504 // Send broadcasts here
21505 Bundle extras = new Bundle();
21506 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
21507 if (uidArr != null) {
21508 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
21511 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
21513 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
21514 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
21515 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null, null);
21519 private void loadPrivatePackages(final VolumeInfo vol) {
21520 mHandler.post(() -> loadPrivatePackagesInner(vol));
21523 private void loadPrivatePackagesInner(VolumeInfo vol) {
21524 final String volumeUuid = vol.fsUuid;
21525 if (TextUtils.isEmpty(volumeUuid)) {
21526 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
21530 final ArrayList<PackageFreezer> freezers = new ArrayList<>();
21531 final ArrayList<AndroidPackage> loaded = new ArrayList<>();
21532 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
21534 final VersionInfo ver;
21535 final List<PackageSetting> packages;
21536 synchronized (mLock) {
21537 ver = mSettings.findOrCreateVersion(volumeUuid);
21538 packages = mSettings.getVolumePackagesLPr(volumeUuid);
21541 for (PackageSetting ps : packages) {
21542 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
21543 synchronized (mInstallLock) {
21544 final AndroidPackage pkg;
21546 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
21549 } catch (PackageManagerException e) {
21550 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
21553 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
21554 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
21555 | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY
21556 | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
21561 // Reconcile app data for all started/unlocked users
21562 final StorageManager sm = mInjector.getStorageManager();
21563 UserManagerInternal umInternal = mInjector.getUserManagerInternal();
21564 for (UserInfo user : mUserManager.getUsers(false /* includeDying */)) {
21566 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21567 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21568 } else if (umInternal.isUserRunning(user.id)) {
21569 flags = StorageManager.FLAG_STORAGE_DE;
21575 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
21576 synchronized (mInstallLock) {
21577 reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
21579 } catch (IllegalStateException e) {
21580 // Device was probably ejected, and we'll process that event momentarily
21581 Slog.w(TAG, "Failed to prepare storage: " + e);
21585 synchronized (mLock) {
21586 final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
21588 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21589 + mSdkVersion + "; regranting permissions for " + volumeUuid);
21591 mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated);
21593 // Yay, everything is now upgraded
21594 ver.forceCurrent();
21596 mSettings.writeLPr();
21599 for (PackageFreezer freezer : freezers) {
21603 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
21604 sendResourcesChangedBroadcast(true, false, loaded, null);
21605 mLoadedVolumes.add(vol.getId());
21608 private void unloadPrivatePackages(final VolumeInfo vol) {
21609 mHandler.post(() -> unloadPrivatePackagesInner(vol));
21612 private void unloadPrivatePackagesInner(VolumeInfo vol) {
21613 final String volumeUuid = vol.fsUuid;
21614 if (TextUtils.isEmpty(volumeUuid)) {
21615 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
21619 final ArrayList<AndroidPackage> unloaded = new ArrayList<>();
21620 synchronized (mInstallLock) {
21621 synchronized (mLock) {
21622 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
21623 for (PackageSetting ps : packages) {
21624 if (ps.pkg == null) continue;
21626 final AndroidPackage pkg = ps.pkg;
21627 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21628 final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
21630 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
21631 "unloadPrivatePackagesInner")) {
21632 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
21636 Slog.w(TAG, "Failed to unload " + ps.codePath);
21640 // Try very hard to release any references to this package
21641 // so we don't risk the system server being killed due to
21643 AttributeCache.instance().removePackage(ps.name);
21646 mSettings.writeLPr();
21650 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
21651 sendResourcesChangedBroadcast(false, false, unloaded, null);
21652 mLoadedVolumes.remove(vol.getId());
21654 // Try very hard to release any references to this path so we don't risk
21655 // the system server being killed due to open FDs
21656 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
21658 for (int i = 0; i < 3; i++) {
21660 System.runFinalization();
21664 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
21665 throws PackageManagerException {
21666 synchronized (mLock) {
21667 // Normalize package name to handle renamed packages
21668 packageName = normalizePackageNameLPr(packageName);
21670 final PackageSetting ps = mSettings.mPackages.get(packageName);
21672 throw new PackageManagerException("Package " + packageName + " is unknown");
21673 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21674 throw new PackageManagerException(
21675 "Package " + packageName + " found on unknown volume " + volumeUuid
21676 + "; expected volume " + ps.volumeUuid);
21677 } else if (!ps.getInstalled(userId)) {
21678 throw new PackageManagerException(
21679 "Package " + packageName + " not installed for user " + userId);
21684 private List<String> collectAbsoluteCodePaths() {
21685 synchronized (mLock) {
21686 List<String> codePaths = new ArrayList<>();
21687 final int packageCount = mSettings.mPackages.size();
21688 for (int i = 0; i < packageCount; i++) {
21689 final PackageSetting ps = mSettings.mPackages.valueAt(i);
21690 codePaths.add(ps.codePath.getAbsolutePath());
21697 * Examine all apps present on given mounted volume, and destroy apps that
21698 * aren't expected, either due to uninstallation or reinstallation on
21701 private void reconcileApps(String volumeUuid) {
21702 List<String> absoluteCodePaths = collectAbsoluteCodePaths();
21703 List<File> filesToDelete = null;
21705 final File[] files = FileUtils.listFilesOrEmpty(
21706 Environment.getDataAppDirectory(volumeUuid));
21707 for (File file : files) {
21708 final boolean isPackage = (isApkFile(file) || file.isDirectory())
21709 && !PackageInstallerService.isStageName(file.getName());
21711 // Ignore entries which are not packages
21715 String absolutePath = file.getAbsolutePath();
21717 boolean pathValid = false;
21718 final int absoluteCodePathCount = absoluteCodePaths.size();
21719 for (int i = 0; i < absoluteCodePathCount; i++) {
21720 String absoluteCodePath = absoluteCodePaths.get(i);
21721 if (absoluteCodePath.startsWith(absolutePath)) {
21728 if (filesToDelete == null) {
21729 filesToDelete = new ArrayList<>();
21731 filesToDelete.add(file);
21735 if (filesToDelete != null) {
21736 final int fileToDeleteCount = filesToDelete.size();
21737 for (int i = 0; i < fileToDeleteCount; i++) {
21738 File fileToDelete = filesToDelete.get(i);
21739 logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
21740 synchronized (mInstallLock) {
21741 removeCodePathLI(fileToDelete);
21748 * Reconcile all app data for the given user.
21750 * Verifies that directories exist and that ownership and labeling is
21751 * correct for all installed apps on all mounted volumes.
21753 void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
21754 final StorageManager storage = mInjector.getStorageManager();
21755 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
21756 final String volumeUuid = vol.getFsUuid();
21757 synchronized (mInstallLock) {
21758 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
21763 @GuardedBy("mInstallLock")
21764 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21765 boolean migrateAppData) {
21766 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
21770 * Reconcile all app data on given mounted volume.
21772 * Destroys app data that isn't expected, either due to uninstallation or
21773 * reinstallation on another volume.
21775 * Verifies that directories exist and that ownership and labeling is
21776 * correct for all installed apps.
21777 * @return list of skipped non-core packages (if {@code onlyCoreApps} is true)
21779 @GuardedBy("mInstallLock")
21780 private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21781 boolean migrateAppData, boolean onlyCoreApps) {
21782 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
21783 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
21784 List<String> result = onlyCoreApps ? new ArrayList<>() : null;
21786 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
21787 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
21789 // First look for stale data that doesn't belong, and check if things
21790 // have changed since we did our last restorecon
21791 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
21792 if (StorageManager.isFileEncryptedNativeOrEmulated()
21793 && !StorageManager.isUserKeyUnlocked(userId)) {
21794 throw new RuntimeException(
21795 "Yikes, someone asked us to reconcile CE storage while " + userId
21796 + " was still locked; this would have caused massive data loss!");
21799 final File[] files = FileUtils.listFilesOrEmpty(ceDir);
21800 for (File file : files) {
21801 final String packageName = file.getName();
21803 assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21804 } catch (PackageManagerException e) {
21805 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21807 mInstaller.destroyAppData(volumeUuid, packageName, userId,
21808 StorageManager.FLAG_STORAGE_CE, 0);
21809 } catch (InstallerException e2) {
21810 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21815 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
21816 final File[] files = FileUtils.listFilesOrEmpty(deDir);
21817 for (File file : files) {
21818 final String packageName = file.getName();
21820 assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21821 } catch (PackageManagerException e) {
21822 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21824 mInstaller.destroyAppData(volumeUuid, packageName, userId,
21825 StorageManager.FLAG_STORAGE_DE, 0);
21826 } catch (InstallerException e2) {
21827 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21833 // Ensure that data directories are ready to roll for all packages
21834 // installed for this volume and user
21835 final List<PackageSetting> packages;
21836 synchronized (mLock) {
21837 packages = mSettings.getVolumePackagesLPr(volumeUuid);
21839 int preparedCount = 0;
21840 for (PackageSetting ps : packages) {
21841 final String packageName = ps.name;
21842 if (ps.pkg == null) {
21843 Slog.w(TAG, "Odd, missing scanned package " + packageName);
21844 // TODO: might be due to legacy ASEC apps; we should circle back
21845 // and reconcile again once they're scanned
21848 // Skip non-core apps if requested
21849 if (onlyCoreApps && !ps.pkg.isCoreApp()) {
21850 result.add(packageName);
21854 if (ps.getInstalled(userId)) {
21855 prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
21860 Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
21865 * Prepare app data for the given app just after it was installed or
21866 * upgraded. This method carefully only touches users that it's installed
21867 * for, and it forces a restorecon to handle any seinfo changes.
21869 * Verifies that directories exist and that ownership and labeling is
21870 * correct for all installed apps. If there is an ownership mismatch, it
21871 * will try recovering system apps by wiping data; third-party app data is
21874 * <em>Note: To avoid a deadlock, do not call this method with {@code mLock} lock held</em>
21876 private void prepareAppDataAfterInstallLIF(AndroidPackage pkg) {
21877 final PackageSetting ps;
21878 synchronized (mLock) {
21879 ps = mSettings.mPackages.get(pkg.getPackageName());
21880 mSettings.writeKernelMappingLPr(ps);
21883 UserManagerInternal umInternal = mInjector.getUserManagerInternal();
21884 StorageManagerInternal smInternal = mInjector.getStorageManagerInternal();
21885 for (UserInfo user : mUserManager.getUsers(false /*excludeDying*/)) {
21887 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21888 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21889 } else if (umInternal.isUserRunning(user.id)) {
21890 flags = StorageManager.FLAG_STORAGE_DE;
21895 if (ps.getInstalled(user.id)) {
21896 // TODO: when user data is locked, mark that we're still dirty
21897 prepareAppDataLIF(pkg, user.id, flags);
21899 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21900 // Prepare app data on external storage; currently this is used to
21901 // setup any OBB dirs that were created by the installer correctly.
21902 int uid = UserHandle.getUid(user.id, UserHandle.getAppId(pkg.getUid()));
21903 smInternal.prepareAppDataAfterInstall(pkg.getPackageName(), uid);
21910 * Prepare app data for the given app.
21912 * Verifies that directories exist and that ownership and labeling is
21913 * correct for all installed apps. If there is an ownership mismatch, this
21914 * will try recovering system apps by wiping data; third-party app data is
21917 private void prepareAppDataLIF(AndroidPackage pkg, int userId, int flags) {
21919 Slog.wtf(TAG, "Package was null!", new Throwable());
21922 prepareAppDataLeafLIF(pkg, userId, flags);
21925 private void prepareAppDataAndMigrateLIF(AndroidPackage pkg, int userId, int flags,
21926 boolean maybeMigrateAppData) {
21927 prepareAppDataLIF(pkg, userId, flags);
21929 if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
21930 // We may have just shuffled around app data directories, so
21931 // prepare them one more time
21932 prepareAppDataLIF(pkg, userId, flags);
21936 private void prepareAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
21937 if (DEBUG_APP_DATA) {
21938 Slog.v(TAG, "prepareAppData for " + pkg.getPackageName() + " u" + userId + " 0x"
21939 + Integer.toHexString(flags));
21942 final PackageSetting ps;
21943 synchronized (mLock) {
21944 ps = mSettings.mPackages.get(pkg.getPackageName());
21946 final String volumeUuid = pkg.getVolumeUuid();
21947 final String packageName = pkg.getPackageName();
21949 final int appId = UserHandle.getAppId(pkg.getUid());
21951 String pkgSeInfo = AndroidPackageUtils.getSeInfo(pkg, ps);
21953 Preconditions.checkNotNull(pkgSeInfo);
21955 final String seInfo = pkgSeInfo + (pkg.getSeInfoUser() != null ? pkg.getSeInfoUser() : "");
21956 long ceDataInode = -1;
21958 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21959 appId, seInfo, pkg.getTargetSdkVersion());
21960 } catch (InstallerException e) {
21961 if (pkg.isSystem()) {
21962 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
21963 + ", but trying to recover: " + e);
21964 destroyAppDataLeafLIF(pkg, userId, flags);
21966 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21967 appId, seInfo, pkg.getTargetSdkVersion());
21968 logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
21969 } catch (InstallerException e2) {
21970 logCriticalInfo(Log.DEBUG, "Recovery failed!");
21973 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
21976 // Prepare the application profiles only for upgrades and first boot (so that we don't
21977 // repeat the same operation at each boot).
21978 // We only have to cover the upgrade and first boot here because for app installs we
21979 // prepare the profiles before invoking dexopt (in installPackageLI).
21981 // We also have to cover non system users because we do not call the usual install package
21982 // methods for them.
21984 // NOTE: in order to speed up first boot time we only create the current profile and do not
21985 // update the content of the reference profile. A system image should already be configured
21986 // with the right profile keys and the profiles for the speed-profile prebuilds should
21987 // already be copied. That's done in #performDexOptUpgrade.
21989 // TODO(calin, mathieuc): We should use .dm files for prebuilds profiles instead of
21990 // manually copying them in #performDexOptUpgrade. When we do that we should have a more
21991 // granular check here and only update the existing profiles.
21992 if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) {
21993 mArtManagerService.prepareAppProfiles(pkg, userId,
21994 /* updateReferenceProfileContent= */ false);
21997 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
21998 // TODO: mark this structure as dirty so we persist it!
21999 synchronized (mLock) {
22001 ps.setCeDataInode(ceDataInode, userId);
22006 prepareAppDataContentsLeafLIF(pkg, ps, userId, flags);
22009 private void prepareAppDataContentsLIF(AndroidPackage pkg, @Nullable PackageSetting pkgSetting,
22010 int userId, int flags) {
22012 Slog.wtf(TAG, "Package was null!", new Throwable());
22015 prepareAppDataContentsLeafLIF(pkg, pkgSetting, userId, flags);
22018 private void prepareAppDataContentsLeafLIF(AndroidPackage pkg,
22019 @Nullable PackageSetting pkgSetting, int userId, int flags) {
22020 final String volumeUuid = pkg.getVolumeUuid();
22021 final String packageName = pkg.getPackageName();
22023 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22024 // Create a native library symlink only if we have native libraries
22025 // and if the native libraries are 32 bit libraries. We do not provide
22026 // this symlink for 64 bit libraries.
22027 String primaryCpuAbi = AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting);
22028 if (primaryCpuAbi != null && !VMRuntime.is64BitAbi(primaryCpuAbi)) {
22029 final String nativeLibPath = pkg.getNativeLibraryDir();
22031 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
22032 nativeLibPath, userId);
22033 } catch (InstallerException e) {
22034 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
22041 * For system apps on non-FBE devices, this method migrates any existing
22042 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
22043 * requested by the app.
22045 private boolean maybeMigrateAppDataLIF(AndroidPackage pkg, int userId) {
22046 if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
22047 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
22048 final int storageTarget = pkg.isDefaultToDeviceProtectedStorage()
22049 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
22051 mInstaller.migrateAppData(pkg.getVolumeUuid(), pkg.getPackageName(), userId,
22053 } catch (InstallerException e) {
22054 logCriticalInfo(Log.WARN,
22055 "Failed to migrate " + pkg.getPackageName() + ": " + e.getMessage());
22063 public PackageFreezer freezePackage(String packageName, String killReason) {
22064 return freezePackage(packageName, UserHandle.USER_ALL, killReason);
22067 public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
22068 return new PackageFreezer(packageName, userId, killReason);
22071 public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
22072 String killReason) {
22073 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
22076 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
22077 String killReason) {
22078 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
22079 return new PackageFreezer();
22081 return freezePackage(packageName, userId, killReason);
22085 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
22086 String killReason) {
22087 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
22090 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
22091 String killReason) {
22092 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
22093 return new PackageFreezer();
22095 return freezePackage(packageName, userId, killReason);
22100 * Class that freezes and kills the given package upon creation, and
22101 * unfreezes it upon closing. This is typically used when doing surgery on
22102 * app code/data to prevent the app from running while you're working.
22104 private class PackageFreezer implements AutoCloseable {
22105 private final String mPackageName;
22107 private final boolean mWeFroze;
22109 private final AtomicBoolean mClosed = new AtomicBoolean();
22110 private final CloseGuard mCloseGuard = CloseGuard.get();
22113 * Create and return a stub freezer that doesn't actually do anything,
22114 * typically used when someone requested
22115 * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22116 * {@link PackageManager#DELETE_DONT_KILL_APP}.
22118 public PackageFreezer() {
22119 mPackageName = null;
22121 mCloseGuard.open("close");
22124 public PackageFreezer(String packageName, int userId, String killReason) {
22125 synchronized (mLock) {
22126 mPackageName = packageName;
22127 mWeFroze = mFrozenPackages.add(mPackageName);
22129 final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22131 killApplication(ps.name, ps.appId, userId, killReason);
22134 mCloseGuard.open("close");
22138 protected void finalize() throws Throwable {
22140 mCloseGuard.warnIfOpen();
22148 public void close() {
22149 mCloseGuard.close();
22150 if (mClosed.compareAndSet(false, true)) {
22151 synchronized (mLock) {
22153 mFrozenPackages.remove(mPackageName);
22161 * Verify that given package is currently frozen.
22163 private void checkPackageFrozen(String packageName) {
22164 synchronized (mLock) {
22165 if (!mFrozenPackages.contains(packageName)) {
22166 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
22172 public int movePackage(final String packageName, final String volumeUuid) {
22173 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22175 final int callingUid = Binder.getCallingUid();
22176 final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
22177 final int moveId = mNextMoveId.getAndIncrement();
22178 mHandler.post(() -> {
22180 movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
22181 } catch (PackageManagerException e) {
22182 Slog.w(TAG, "Failed to move " + packageName, e);
22183 mMoveCallbacks.notifyStatusChanged(moveId, e.error);
22189 private void movePackageInternal(final String packageName, final String volumeUuid,
22190 final int moveId, final int callingUid, UserHandle user)
22191 throws PackageManagerException {
22192 final StorageManager storage = mInjector.getStorageManager();
22193 final PackageManager pm = mContext.getPackageManager();
22195 final String currentVolumeUuid;
22196 final File codeFile;
22197 final InstallSource installSource;
22198 final String packageAbiOverride;
22200 final String seinfo;
22201 final String label;
22202 final int targetSdkVersion;
22203 final PackageFreezer freezer;
22204 final int[] installedUserIds;
22205 final boolean isCurrentLocationExternal;
22206 final String fromCodePath;
22209 synchronized (mLock) {
22210 final AndroidPackage pkg = mPackages.get(packageName);
22211 final PackageSetting ps = mSettings.mPackages.get(packageName);
22214 || shouldFilterApplicationLocked(ps, callingUid, user.getIdentifier())) {
22215 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
22217 if (pkg.isSystem()) {
22218 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22219 "Cannot move system application");
22222 final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22223 final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22224 com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22225 if (isInternalStorage && !allow3rdPartyOnInternal) {
22226 throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22227 "3rd party apps are not allowed on internal storage");
22230 currentVolumeUuid = ps.volumeUuid;
22232 final File probe = new File(pkg.getCodePath());
22233 final File probeOat = new File(probe, "oat");
22234 if (!probe.isDirectory() || !probeOat.isDirectory()) {
22235 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22236 "Move only supported for modern cluster style installs");
22239 if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22240 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22241 "Package already moved to " + volumeUuid);
22243 if (!pkg.isExternalStorage() && isPackageDeviceAdminOnAnyUser(packageName)) {
22244 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
22245 "Device admin cannot be moved");
22248 if (mFrozenPackages.contains(packageName)) {
22249 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
22250 "Failed to move already frozen package");
22253 isCurrentLocationExternal = pkg.isExternalStorage();
22254 codeFile = new File(pkg.getCodePath());
22255 installSource = ps.installSource;
22256 packageAbiOverride = ps.cpuAbiOverrideString;
22257 appId = UserHandle.getAppId(pkg.getUid());
22258 seinfo = AndroidPackageUtils.getSeInfo(pkg, ps);
22259 label = String.valueOf(pm.getApplicationLabel(pkg.toAppInfoWithoutState()));
22260 targetSdkVersion = pkg.getTargetSdkVersion();
22261 freezer = freezePackage(packageName, "movePackageInternal");
22262 installedUserIds = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
22263 if (codeFile.getParentFile().getName().startsWith(RANDOM_DIR_PREFIX)) {
22264 fromCodePath = codeFile.getParentFile().getAbsolutePath();
22266 fromCodePath = codeFile.getAbsolutePath();
22270 final Bundle extras = new Bundle();
22271 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
22272 extras.putString(Intent.EXTRA_TITLE, label);
22273 mMoveCallbacks.notifyCreated(moveId, extras);
22276 final boolean moveCompleteApp;
22277 final File measurePath;
22279 installFlags = INSTALL_INTERNAL;
22280 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
22281 moveCompleteApp = true;
22282 measurePath = Environment.getDataAppDirectory(volumeUuid);
22283 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
22284 moveCompleteApp = false;
22285 measurePath = storage.getPrimaryPhysicalVolume().getPath();
22287 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
22288 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
22289 || !volume.isMountedWritable()) {
22291 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22292 "Move location not mounted private volume");
22295 moveCompleteApp = true;
22296 measurePath = Environment.getDataAppDirectory(volumeUuid);
22299 // If we're moving app data around, we need all the users unlocked
22300 if (moveCompleteApp) {
22301 for (int userId : installedUserIds) {
22302 if (StorageManager.isFileEncryptedNativeOrEmulated()
22303 && !StorageManager.isUserKeyUnlocked(userId)) {
22304 throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
22305 "User " + userId + " must be unlocked");
22310 final PackageStats stats = new PackageStats(null, -1);
22311 synchronized (mInstaller) {
22312 for (int userId : installedUserIds) {
22313 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22315 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22316 "Failed to measure package size");
22321 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
22324 final long startFreeBytes = measurePath.getUsableSpace();
22325 final long sizeBytes;
22326 if (moveCompleteApp) {
22327 sizeBytes = stats.codeSize + stats.dataSize;
22329 sizeBytes = stats.codeSize;
22332 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
22334 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22335 "Not enough free space to move");
22338 mMoveCallbacks.notifyStatusChanged(moveId, 10);
22340 final CountDownLatch installedLatch = new CountDownLatch(1);
22341 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
22343 public void onUserActionRequired(Intent intent) throws RemoteException {
22344 throw new IllegalStateException();
22348 public void onPackageInstalled(String basePackageName, int returnCode, String msg,
22349 Bundle extras) throws RemoteException {
22350 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
22351 + PackageManager.installStatusToString(returnCode, msg));
22353 installedLatch.countDown();
22356 final int status = PackageManager.installStatusToPublicStatus(returnCode);
22358 case PackageInstaller.STATUS_SUCCESS:
22359 mMoveCallbacks.notifyStatusChanged(moveId,
22360 PackageManager.MOVE_SUCCEEDED);
22361 logAppMovedStorage(packageName, isCurrentLocationExternal);
22363 case PackageInstaller.STATUS_FAILURE_STORAGE:
22364 mMoveCallbacks.notifyStatusChanged(moveId,
22365 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
22368 mMoveCallbacks.notifyStatusChanged(moveId,
22369 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22375 final MoveInfo move;
22376 if (moveCompleteApp) {
22377 // Kick off a thread to report progress estimates
22381 if (installedLatch.await(1, TimeUnit.SECONDS)) {
22384 } catch (InterruptedException ignored) {
22387 final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
22388 final int progress = 10 + (int) MathUtils.constrain(
22389 ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
22390 mMoveCallbacks.notifyStatusChanged(moveId, progress);
22394 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
22395 appId, seinfo, targetSdkVersion, fromCodePath);
22400 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
22402 final Message msg = mHandler.obtainMessage(INIT_COPY);
22403 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
22404 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
22405 installSource, volumeUuid, null /*verificationInfo*/, user,
22406 packageAbiOverride, null /*grantedPermissions*/,
22407 null /*whitelistedRestrictedPermissions*/, PackageParser.SigningDetails.UNKNOWN,
22408 PackageManager.INSTALL_REASON_UNKNOWN, PackageManager.VERSION_CODE_HIGHEST,
22409 DataLoaderType.NONE);
22410 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
22413 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
22414 System.identityHashCode(msg.obj));
22415 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
22416 System.identityHashCode(msg.obj));
22418 mHandler.sendMessage(msg);
22422 * Logs that an app has been moved from internal to external storage and vice versa.
22423 * @param packageName The package that was moved.
22425 private void logAppMovedStorage(String packageName, boolean isPreviousLocationExternal) {
22426 final AndroidPackage pkg;
22427 synchronized (mLock) {
22428 pkg = mPackages.get(packageName);
22434 final StorageManager storage = mInjector.getStorageManager();;
22435 VolumeInfo volume = storage.findVolumeByUuid(pkg.getStorageUuid().toString());
22436 int packageExternalStorageType = getPackageExternalStorageType(volume, pkg.isExternalStorage());
22438 if (!isPreviousLocationExternal && pkg.isExternalStorage()) {
22439 // Move from internal to external storage.
22440 FrameworkStatsLog.write(FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED,
22441 packageExternalStorageType,
22442 FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_EXTERNAL,
22444 } else if (isPreviousLocationExternal && !pkg.isExternalStorage()) {
22445 // Move from external to internal storage.
22446 FrameworkStatsLog.write(FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED,
22447 packageExternalStorageType,
22448 FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_INTERNAL,
22454 public int movePrimaryStorage(String volumeUuid) throws RemoteException {
22455 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22457 final int realMoveId = mNextMoveId.getAndIncrement();
22458 final Bundle extras = new Bundle();
22459 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
22460 mMoveCallbacks.notifyCreated(realMoveId, extras);
22462 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
22464 public void onCreated(int moveId, Bundle extras) {
22469 public void onStatusChanged(int moveId, int status, long estMillis) {
22470 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
22474 final StorageManager storage = mInjector.getStorageManager();
22475 storage.setPrimaryStorageUuid(volumeUuid, callback);
22480 public int getMoveStatus(int moveId) {
22481 mContext.enforceCallingOrSelfPermission(
22482 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22483 return mMoveCallbacks.mLastStatus.get(moveId);
22487 public void registerMoveCallback(IPackageMoveObserver callback) {
22488 mContext.enforceCallingOrSelfPermission(
22489 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22490 mMoveCallbacks.register(callback);
22494 public void unregisterMoveCallback(IPackageMoveObserver callback) {
22495 mContext.enforceCallingOrSelfPermission(
22496 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22497 mMoveCallbacks.unregister(callback);
22501 public boolean setInstallLocation(int loc) {
22502 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
22504 if (getInstallLocation() == loc) {
22507 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
22508 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
22509 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
22510 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
22517 public int getInstallLocation() {
22518 // allow instant app access
22519 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
22520 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
22521 PackageHelper.APP_INSTALL_AUTO);
22524 /** Called by UserManagerService */
22525 void cleanUpUser(UserManagerService userManager, @UserIdInt int userId) {
22526 synchronized (mLock) {
22527 mDirtyUsers.remove(userId);
22528 mUserNeedsBadging.delete(userId);
22529 mSettings.removeUserLPw(userId);
22530 mPendingBroadcasts.remove(userId);
22531 mInstantAppRegistry.onUserRemovedLPw(userId);
22532 removeUnusedPackagesLPw(userManager, userId);
22537 * We're removing userId and would like to remove any downloaded packages
22538 * that are no longer in use by any other user.
22539 * @param userId the user being removed
22541 @GuardedBy("mLock")
22542 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userId) {
22543 final boolean DEBUG_CLEAN_APKS = false;
22544 int [] users = userManager.getUserIds();
22545 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
22546 while (psit.hasNext()) {
22547 PackageSetting ps = psit.next();
22548 if (ps.pkg == null) {
22551 final String packageName = ps.pkg.getPackageName();
22552 // Skip over if system app or static shared library
22553 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0
22554 || !TextUtils.isEmpty(ps.pkg.getStaticSharedLibName())) {
22557 if (DEBUG_CLEAN_APKS) {
22558 Slog.i(TAG, "Checking package " + packageName);
22560 boolean keep = shouldKeepUninstalledPackageLPr(packageName);
22562 if (DEBUG_CLEAN_APKS) {
22563 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO");
22566 for (int i = 0; i < users.length; i++) {
22567 if (users[i] != userId && ps.getInstalled(users[i])) {
22569 if (DEBUG_CLEAN_APKS) {
22570 Slog.i(TAG, " Keeping package " + packageName + " for user "
22578 if (DEBUG_CLEAN_APKS) {
22579 Slog.i(TAG, " Removing package " + packageName);
22582 mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22589 * Called by UserManagerService.
22591 * @param installablePackages system packages that should be initially installed for this user,
22592 * or {@code null} if all system packages should be installed
22593 * @param disallowedPackages packages that should not be initially installed. Takes precedence
22594 * over installablePackages.
22596 void createNewUser(int userId, @Nullable Set<String> installablePackages,
22597 String[] disallowedPackages) {
22598 synchronized (mInstallLock) {
22599 mSettings.createNewUserLI(this, mInstaller, userId,
22600 installablePackages, disallowedPackages);
22602 synchronized (mLock) {
22603 scheduleWritePackageRestrictionsLocked(userId);
22604 scheduleWritePackageListLocked(userId);
22605 primeDomainVerificationsLPw(userId);
22609 void onNewUserCreated(final int userId) {
22610 mPermissionManager.onNewUserCreated(userId);
22613 boolean readPermissionStateForUser(@UserIdInt int userId) {
22614 synchronized (mPackages) {
22615 mSettings.readPermissionStateForUserSyncLPr(userId);
22616 return mSettings.areDefaultRuntimePermissionsGrantedLPr(userId);
22621 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
22622 mContext.enforceCallingOrSelfPermission(
22623 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
22624 "Only package verification agents can read the verifier device identity");
22626 synchronized (mLock) {
22627 return mSettings.getVerifierDeviceIdentityLPw();
22632 public boolean isStorageLow() {
22633 // allow instant applications
22634 final long token = Binder.clearCallingIdentity();
22636 final DeviceStorageMonitorInternal
22637 dsm = mInjector.getDeviceStorageMonitorInternal();
22639 return dsm.isMemoryLow();
22644 Binder.restoreCallingIdentity(token);
22649 public IPackageInstaller getPackageInstaller() {
22650 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
22653 return mInstallerService;
22657 public IArtManager getArtManager() {
22658 return mArtManagerService;
22661 private boolean userNeedsBadging(int userId) {
22662 int index = mUserNeedsBadging.indexOfKey(userId);
22664 final UserInfo userInfo;
22665 final long token = Binder.clearCallingIdentity();
22667 userInfo = mUserManager.getUserInfo(userId);
22669 Binder.restoreCallingIdentity(token);
22672 if (userInfo != null && userInfo.isManagedProfile()) {
22677 mUserNeedsBadging.put(userId, b);
22680 return mUserNeedsBadging.valueAt(index);
22684 public KeySet getKeySetByAlias(String packageName, String alias) {
22685 if (packageName == null || alias == null) {
22688 synchronized(mLock) {
22689 final AndroidPackage pkg = mPackages.get(packageName);
22691 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22692 throw new IllegalArgumentException("Unknown package: " + packageName);
22694 final PackageSetting ps = getPackageSetting(pkg.getPackageName());
22695 if (shouldFilterApplicationLocked(
22696 ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
22697 Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
22698 throw new IllegalArgumentException("Unknown package: " + packageName);
22700 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22701 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
22706 public KeySet getSigningKeySet(String packageName) {
22707 if (packageName == null) {
22710 synchronized (mLock) {
22711 final int callingUid = Binder.getCallingUid();
22712 final int callingUserId = UserHandle.getUserId(callingUid);
22713 final AndroidPackage pkg = mPackages.get(packageName);
22715 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22716 throw new IllegalArgumentException("Unknown package: " + packageName);
22718 final PackageSetting ps = getPackageSetting(pkg.getPackageName());
22719 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
22720 // filter and pretend the package doesn't exist
22721 Slog.w(TAG, "KeySet requested for filtered package: " + packageName
22722 + ", uid:" + callingUid);
22723 throw new IllegalArgumentException("Unknown package: " + packageName);
22725 if (pkg.getUid() != callingUid
22726 && Process.SYSTEM_UID != callingUid) {
22727 throw new SecurityException("May not access signing KeySet of other apps.");
22729 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22730 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
22735 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
22736 final int callingUid = Binder.getCallingUid();
22737 if (getInstantAppPackageName(callingUid) != null) {
22740 if (packageName == null || ks == null) {
22743 synchronized(mLock) {
22744 final AndroidPackage pkg = mPackages.get(packageName);
22746 || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
22747 callingUid, UserHandle.getUserId(callingUid))) {
22748 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22749 throw new IllegalArgumentException("Unknown package: " + packageName);
22751 IBinder ksh = ks.getToken();
22752 if (ksh instanceof KeySetHandle) {
22753 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22754 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
22761 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
22762 final int callingUid = Binder.getCallingUid();
22763 if (getInstantAppPackageName(callingUid) != null) {
22766 if (packageName == null || ks == null) {
22769 synchronized (mLock) {
22770 final AndroidPackage pkg = mPackages.get(packageName);
22772 || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
22773 callingUid, UserHandle.getUserId(callingUid))) {
22774 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22775 throw new IllegalArgumentException("Unknown package: " + packageName);
22777 IBinder ksh = ks.getToken();
22778 if (ksh instanceof KeySetHandle) {
22779 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22780 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
22786 @GuardedBy("mLock")
22787 private void deletePackageIfUnusedLPr(final String packageName) {
22788 PackageSetting ps = mSettings.mPackages.get(packageName);
22792 if (!ps.isAnyInstalled(mUserManager.getUserIds())) {
22793 // TODO Implement atomic delete if package is unused
22794 // It is currently possible that the package will be deleted even if it is installed
22795 // after this method returns.
22796 mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22797 0, PackageManager.DELETE_ALL_USERS));
22802 * Check and throw if the given before/after packages would be considered a
22805 private static void checkDowngrade(AndroidPackage before, PackageInfoLite after)
22806 throws PackageManagerException {
22807 if (after.getLongVersionCode() < before.getLongVersionCode()) {
22808 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22809 "Update version code " + after.versionCode + " is older than current "
22810 + before.getLongVersionCode());
22811 } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
22812 if (after.baseRevisionCode < before.getBaseRevisionCode()) {
22813 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22814 "Update base revision code " + after.baseRevisionCode
22815 + " is older than current " + before.getBaseRevisionCode());
22818 if (!ArrayUtils.isEmpty(after.splitNames)) {
22819 for (int i = 0; i < after.splitNames.length; i++) {
22820 final String splitName = after.splitNames[i];
22821 final int j = ArrayUtils.indexOf(before.getSplitNames(), splitName);
22823 if (after.splitRevisionCodes[i] < before.getSplitRevisionCodes()[j]) {
22824 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22825 "Update split " + splitName + " revision code "
22826 + after.splitRevisionCodes[i] + " is older than current "
22827 + before.getSplitRevisionCodes()[j]);
22835 private static class MoveCallbacks extends Handler {
22836 private static final int MSG_CREATED = 1;
22837 private static final int MSG_STATUS_CHANGED = 2;
22839 private final RemoteCallbackList<IPackageMoveObserver>
22840 mCallbacks = new RemoteCallbackList<>();
22842 private final SparseIntArray mLastStatus = new SparseIntArray();
22844 public MoveCallbacks(Looper looper) {
22848 public void register(IPackageMoveObserver callback) {
22849 mCallbacks.register(callback);
22852 public void unregister(IPackageMoveObserver callback) {
22853 mCallbacks.unregister(callback);
22857 public void handleMessage(Message msg) {
22858 final SomeArgs args = (SomeArgs) msg.obj;
22859 final int n = mCallbacks.beginBroadcast();
22860 for (int i = 0; i < n; i++) {
22861 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
22863 invokeCallback(callback, msg.what, args);
22864 } catch (RemoteException ignored) {
22867 mCallbacks.finishBroadcast();
22871 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
22872 throws RemoteException {
22874 case MSG_CREATED: {
22875 callback.onCreated(args.argi1, (Bundle) args.arg2);
22878 case MSG_STATUS_CHANGED: {
22879 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
22885 private void notifyCreated(int moveId, Bundle extras) {
22886 Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
22888 final SomeArgs args = SomeArgs.obtain();
22889 args.argi1 = moveId;
22890 args.arg2 = extras;
22891 obtainMessage(MSG_CREATED, args).sendToTarget();
22894 private void notifyStatusChanged(int moveId, int status) {
22895 notifyStatusChanged(moveId, status, -1);
22898 private void notifyStatusChanged(int moveId, int status, long estMillis) {
22899 Slog.v(TAG, "Move " + moveId + " status " + status);
22901 final SomeArgs args = SomeArgs.obtain();
22902 args.argi1 = moveId;
22903 args.argi2 = status;
22904 args.arg3 = estMillis;
22905 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
22907 synchronized (mLastStatus) {
22908 mLastStatus.put(moveId, status);
22913 private class PackageManagerNative extends IPackageManagerNative.Stub {
22915 public String[] getAllPackages() {
22916 return PackageManagerService.this.getAllPackages().toArray(new String[0]);
22920 public String[] getNamesForUids(int[] uids) throws RemoteException {
22921 final String[] results = PackageManagerService.this.getNamesForUids(uids);
22922 // massage results so they can be parsed by the native binder
22923 for (int i = results.length - 1; i >= 0; --i) {
22924 if (results[i] == null) {
22931 // NB: this differentiates between preloads and sideloads
22933 public String getInstallerForPackage(String packageName) throws RemoteException {
22934 final String installerName = getInstallerPackageName(packageName);
22935 if (!TextUtils.isEmpty(installerName)) {
22936 return installerName;
22938 // differentiate between preload and sideload
22939 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22940 ApplicationInfo appInfo = getApplicationInfo(packageName,
22942 /*userId*/ callingUser);
22943 if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22950 public long getVersionCodeForPackage(String packageName) throws RemoteException {
22952 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22953 PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
22954 if (pInfo != null) {
22955 return pInfo.getLongVersionCode();
22957 } catch (Exception e) {
22963 public int getTargetSdkVersionForPackage(String packageName)
22964 throws RemoteException {
22965 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22966 ApplicationInfo info = getApplicationInfo(packageName, 0, callingUser);
22967 if (info == null) {
22968 throw new RemoteException(
22969 "Couldn't get ApplicationInfo for package " + packageName);
22971 return info.targetSdkVersion;
22975 public boolean[] isAudioPlaybackCaptureAllowed(String[] packageNames)
22976 throws RemoteException {
22977 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22978 boolean[] results = new boolean[packageNames.length];
22979 for (int i = results.length - 1; i >= 0; --i) {
22980 ApplicationInfo appInfo = getApplicationInfo(packageNames[i], 0, callingUser);
22981 results[i] = appInfo == null ? false : appInfo.isAudioPlaybackCaptureAllowed();
22987 public int getLocationFlags(String packageName) throws RemoteException {
22988 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22989 ApplicationInfo appInfo = getApplicationInfo(packageName,
22991 /*userId*/ callingUser);
22992 if (appInfo == null) {
22993 throw new RemoteException(
22994 "Couldn't get ApplicationInfo for package " + packageName);
22996 return ((appInfo.isSystemApp() ? IPackageManagerNative.LOCATION_SYSTEM : 0)
22997 | (appInfo.isVendor() ? IPackageManagerNative.LOCATION_VENDOR : 0)
22998 | (appInfo.isProduct() ? IPackageManagerNative.LOCATION_PRODUCT : 0));
23002 public String getModuleMetadataPackageName() throws RemoteException {
23003 return PackageManagerService.this.mModuleInfoProvider.getPackageName();
23007 private class PackageManagerInternalImpl extends PackageManagerInternal {
23009 public List<ApplicationInfo> getInstalledApplications(int flags, int userId,
23011 return PackageManagerService.this.getInstalledApplicationsListInternal(flags, userId,
23017 public boolean isPlatformSigned(String packageName) {
23018 PackageSetting packageSetting = mSettings.mPackages.get(packageName);
23019 if (packageSetting == null) {
23022 AndroidPackage pkg = packageSetting.pkg;
23024 // May happen if package in on a removable sd card
23027 return pkg.getSigningDetails().hasAncestorOrSelf(mPlatformPackage.getSigningDetails())
23028 || mPlatformPackage.getSigningDetails().checkCapability(pkg.getSigningDetails(),
23029 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
23033 public boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName) {
23034 SigningDetails sd = getSigningDetails(packageName);
23038 return sd.hasSha256Certificate(restoringFromSigHash,
23039 SigningDetails.CertCapabilities.INSTALLED_DATA);
23043 public boolean isDataRestoreSafe(Signature restoringFromSig, String packageName) {
23044 SigningDetails sd = getSigningDetails(packageName);
23048 return sd.hasCertificate(restoringFromSig,
23049 SigningDetails.CertCapabilities.INSTALLED_DATA);
23053 public boolean hasSignatureCapability(int serverUid, int clientUid,
23054 @SigningDetails.CertCapabilities int capability) {
23055 SigningDetails serverSigningDetails = getSigningDetails(serverUid);
23056 SigningDetails clientSigningDetails = getSigningDetails(clientUid);
23057 return serverSigningDetails.checkCapability(clientSigningDetails, capability)
23058 || clientSigningDetails.hasAncestorOrSelf(serverSigningDetails);
23062 private SigningDetails getSigningDetails(@NonNull String packageName) {
23063 synchronized (mLock) {
23064 AndroidPackage p = mPackages.get(packageName);
23068 return p.getSigningDetails();
23072 private SigningDetails getSigningDetails(int uid) {
23073 synchronized (mLock) {
23074 final int appId = UserHandle.getAppId(uid);
23075 final Object obj = mSettings.getSettingLPr(appId);
23077 if (obj instanceof SharedUserSetting) {
23078 return ((SharedUserSetting) obj).signatures.mSigningDetails;
23079 } else if (obj instanceof PackageSetting) {
23080 final PackageSetting ps = (PackageSetting) obj;
23081 return ps.signatures.mSigningDetails;
23084 return SigningDetails.UNKNOWN;
23089 public boolean isInstantApp(String packageName, int userId) {
23090 return PackageManagerService.this.isInstantApp(packageName, userId);
23094 public String getInstantAppPackageName(int uid) {
23095 return PackageManagerService.this.getInstantAppPackageName(uid);
23099 public boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
23100 synchronized (mLock) {
23101 PackageSetting ps = getPackageSetting(pkg.getPackageName());
23102 return PackageManagerService.this.shouldFilterApplicationLocked(ps, callingUid,
23108 public boolean filterAppAccess(String packageName, int callingUid, int userId) {
23109 synchronized (mLock) {
23110 PackageSetting ps = getPackageSetting(packageName);
23111 return PackageManagerService.this.shouldFilterApplicationLocked(ps, callingUid,
23117 public AndroidPackage getPackage(String packageName) {
23118 synchronized (mLock) {
23119 packageName = resolveInternalPackageNameLPr(
23120 packageName, PackageManager.VERSION_CODE_HIGHEST);
23121 return mPackages.get(packageName);
23126 public AndroidPackage getPackage(int uid) {
23127 synchronized (mLock) {
23128 final String[] packageNames = getPackagesForUidInternal(uid, Process.SYSTEM_UID);
23129 AndroidPackage pkg = null;
23130 final int numPackages = packageNames == null ? 0 : packageNames.length;
23131 for (int i = 0; pkg == null && i < numPackages; i++) {
23132 pkg = mPackages.get(packageNames[i]);
23140 public PackageSetting getPackageSetting(String packageName) {
23141 return PackageManagerService.this.getPackageSetting(packageName);
23145 public PackageList getPackageList(PackageListObserver observer) {
23146 synchronized (mLock) {
23147 final int N = mPackages.size();
23148 final ArrayList<String> list = new ArrayList<>(N);
23149 for (int i = 0; i < N; i++) {
23150 list.add(mPackages.keyAt(i));
23152 final PackageList packageList = new PackageList(list, observer);
23153 if (observer != null) {
23154 mPackageListObservers.add(packageList);
23156 return packageList;
23161 public void removePackageListObserver(PackageListObserver observer) {
23162 synchronized (mLock) {
23163 mPackageListObservers.remove(observer);
23168 public PackageSetting getDisabledSystemPackage(@NonNull String packageName) {
23169 synchronized (mLock) {
23170 return mSettings.getDisabledSystemPkgLPr(packageName);
23176 String getDisabledSystemPackageName(@NonNull String packageName) {
23177 PackageSetting disabledPkgSetting = (PackageSetting) getDisabledSystemPackage(
23179 AndroidPackage disabledPkg = disabledPkgSetting == null ? null : disabledPkgSetting.pkg;
23180 return disabledPkg == null ? null : disabledPkg.getPackageName();
23184 * Only keep package names that refer to {@link PackageParser.Package#isSystem system}
23187 * @param pkgNames The packages to filter
23189 * @return The filtered packages
23191 private @NonNull String[] filterOnlySystemPackages(@Nullable String... pkgNames) {
23192 if (pkgNames == null) {
23193 return ArrayUtils.emptyArray(String.class);
23196 ArrayList<String> systemPackageNames = new ArrayList<>(pkgNames.length);
23198 for (String pkgName: pkgNames) {
23199 synchronized (mLock) {
23200 if (pkgName == null) {
23204 AndroidPackage pkg = getPackage(pkgName);
23206 Log.w(TAG, "Could not find package " + pkgName);
23210 if (!pkg.isSystem()) {
23211 Log.w(TAG, pkgName + " is not system");
23215 systemPackageNames.add(pkgName);
23219 return systemPackageNames.toArray(new String[]{});
23223 public @NonNull String[] getKnownPackageNames(int knownPackage, int userId) {
23224 return dropNonSystemPackages(getKnownPackageNamesInternal(knownPackage, userId));
23227 private String[] getKnownPackageNamesInternal(int knownPackage, int userId) {
23228 switch (knownPackage) {
23229 case PackageManagerInternal.PACKAGE_BROWSER:
23230 return new String[]{mPermissionManager.getDefaultBrowser(userId)};
23231 case PackageManagerInternal.PACKAGE_INSTALLER:
23232 return filterOnlySystemPackages(mRequiredInstallerPackage);
23233 case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
23234 return filterOnlySystemPackages(mSetupWizardPackage);
23235 case PackageManagerInternal.PACKAGE_SYSTEM:
23236 return new String[]{"android"};
23237 case PackageManagerInternal.PACKAGE_VERIFIER:
23238 return filterOnlySystemPackages(mRequiredVerifierPackage);
23239 case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER:
23240 return filterOnlySystemPackages(
23241 mDefaultTextClassifierPackage, mSystemTextClassifierPackageName);
23242 case PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER:
23243 return filterOnlySystemPackages(mRequiredPermissionControllerPackage);
23244 case PackageManagerInternal.PACKAGE_WELLBEING:
23245 return filterOnlySystemPackages(mWellbeingPackage);
23246 case PackageManagerInternal.PACKAGE_DOCUMENTER:
23247 return filterOnlySystemPackages(mDocumenterPackage);
23248 case PackageManagerInternal.PACKAGE_CONFIGURATOR:
23249 return filterOnlySystemPackages(mConfiguratorPackage);
23250 case PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER:
23251 return filterOnlySystemPackages(mIncidentReportApproverPackage);
23252 case PackageManagerInternal.PACKAGE_APP_PREDICTOR:
23253 return filterOnlySystemPackages(mAppPredictionServicePackage);
23254 case PackageManagerInternal.PACKAGE_TELEPHONY:
23255 return filterOnlySystemPackages(mTelephonyPackages);
23256 case PackageManagerInternal.PACKAGE_COMPANION:
23257 return filterOnlySystemPackages("com.android.companiondevicemanager");
23258 case PackageManagerInternal.PACKAGE_RETAIL_DEMO:
23259 return TextUtils.isEmpty(mRetailDemoPackage)
23260 ? ArrayUtils.emptyArray(String.class)
23261 : new String[] {mRetailDemoPackage};
23263 return ArrayUtils.emptyArray(String.class);
23268 public boolean isResolveActivityComponent(ComponentInfo component) {
23269 return mResolveActivity.packageName.equals(component.packageName)
23270 && mResolveActivity.name.equals(component.name);
23274 public void setKeepUninstalledPackages(final List<String> packageList) {
23275 Preconditions.checkNotNull(packageList);
23276 List<String> removedFromList = null;
23277 synchronized (mLock) {
23278 if (mKeepUninstalledPackages != null) {
23279 final int packagesCount = mKeepUninstalledPackages.size();
23280 for (int i = 0; i < packagesCount; i++) {
23281 String oldPackage = mKeepUninstalledPackages.get(i);
23282 if (packageList != null && packageList.contains(oldPackage)) {
23285 if (removedFromList == null) {
23286 removedFromList = new ArrayList<>();
23288 removedFromList.add(oldPackage);
23291 mKeepUninstalledPackages = new ArrayList<>(packageList);
23292 if (removedFromList != null) {
23293 final int removedCount = removedFromList.size();
23294 for (int i = 0; i < removedCount; i++) {
23295 deletePackageIfUnusedLPr(removedFromList.get(i));
23302 public boolean isPermissionsReviewRequired(String packageName, int userId) {
23303 synchronized (mLock) {
23304 final AndroidPackage pkg = mPackages.get(packageName);
23309 return mPermissionManager.isPermissionsReviewRequired(pkg, userId);
23314 public PackageInfo getPackageInfo(
23315 String packageName, int flags, int filterCallingUid, int userId) {
23316 return PackageManagerService.this
23317 .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
23318 flags, filterCallingUid, userId);
23322 public long getCeDataInode(String packageName, int userId) {
23323 synchronized (mLock) {
23324 final PackageSetting ps = mSettings.mPackages.get(packageName);
23326 return ps.getCeDataInode(userId);
23333 public Bundle getSuspendedPackageLauncherExtras(String packageName, int userId) {
23334 synchronized (mLock) {
23335 final PackageSetting ps = mSettings.mPackages.get(packageName);
23336 final Bundle allExtras = new Bundle();
23338 final PackageUserState pus = ps.readUserState(userId);
23339 if (pus.suspended) {
23340 for (int i = 0; i < pus.suspendParams.size(); i++) {
23341 final PackageUserState.SuspendParams params =
23342 pus.suspendParams.valueAt(i);
23343 if (params != null && params.launcherExtras != null) {
23344 allExtras.putAll(params.launcherExtras);
23350 return (allExtras.size() > 0) ? allExtras : null;
23355 public boolean isPackageSuspended(String packageName, int userId) {
23356 synchronized (mLock) {
23357 final PackageSetting ps = mSettings.mPackages.get(packageName);
23358 return (ps != null) ? ps.getSuspended(userId) : false;
23363 public void removeAllNonSystemPackageSuspensions(int userId) {
23364 final String[] allPackages;
23365 synchronized (mLock) {
23366 allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
23368 PackageManagerService.this.removeSuspensionsBySuspendingPackage(allPackages,
23369 (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
23374 public void removeNonSystemPackageSuspensions(String packageName, int userId) {
23375 PackageManagerService.this.removeSuspensionsBySuspendingPackage(
23376 new String[]{packageName},
23377 (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
23382 public void flushPackageRestrictions(int userId) {
23383 synchronized (mLock) {
23384 PackageManagerService.this.flushPackageRestrictionsAsUserInternalLocked(userId);
23389 public void removeDistractingPackageRestrictions(String packageName, int userId) {
23390 PackageManagerService.this.removeDistractingPackageRestrictions(
23391 new String[]{packageName}, userId);
23395 public void removeAllDistractingPackageRestrictions(int userId) {
23396 PackageManagerService.this.removeAllDistractingPackageRestrictions(userId);
23400 public String getSuspendingPackage(String suspendedPackage, int userId) {
23401 synchronized (mLock) {
23402 final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
23404 final PackageUserState pus = ps.readUserState(userId);
23405 if (pus.suspended) {
23406 String suspendingPackage = null;
23407 for (int i = 0; i < pus.suspendParams.size(); i++) {
23408 suspendingPackage = pus.suspendParams.keyAt(i);
23409 if (PLATFORM_PACKAGE_NAME.equals(suspendingPackage)) {
23410 return suspendingPackage;
23413 return suspendingPackage;
23421 public SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage,
23422 String suspendingPackage, int userId) {
23423 synchronized (mLock) {
23424 final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
23426 final PackageUserState pus = ps.readUserState(userId);
23427 if (pus.suspended) {
23428 final PackageUserState.SuspendParams suspendParams =
23429 pus.suspendParams.get(suspendingPackage);
23430 return (suspendParams != null) ? suspendParams.dialogInfo : null;
23438 public int getDistractingPackageRestrictions(String packageName, int userId) {
23439 synchronized (mLock) {
23440 final PackageSetting ps = mSettings.mPackages.get(packageName);
23441 return (ps != null) ? ps.getDistractionFlags(userId) : RESTRICTION_NONE;
23446 public int getPackageUid(String packageName, int flags, int userId) {
23447 return PackageManagerService.this
23448 .getPackageUid(packageName, flags, userId);
23452 public int getPackageUidInternal(String packageName, int flags, int userId) {
23453 return PackageManagerService.this
23454 .getPackageUidInternal(packageName, flags, userId, Process.SYSTEM_UID);
23458 public ApplicationInfo getApplicationInfo(
23459 String packageName, int flags, int filterCallingUid, int userId) {
23460 return PackageManagerService.this
23461 .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
23465 public ActivityInfo getActivityInfo(
23466 ComponentName component, int flags, int filterCallingUid, int userId) {
23467 return PackageManagerService.this
23468 .getActivityInfoInternal(component, flags, filterCallingUid, userId);
23472 public List<ResolveInfo> queryIntentActivities(
23473 Intent intent, String resolvedType, int flags, int filterCallingUid, int userId) {
23474 return PackageManagerService.this
23475 .queryIntentActivitiesInternal(intent, resolvedType, flags, 0, filterCallingUid,
23476 userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
23480 public List<ResolveInfo> queryIntentServices(
23481 Intent intent, int flags, int callingUid, int userId) {
23482 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23483 return PackageManagerService.this
23484 .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
23489 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23491 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
23495 public ComponentName getDefaultHomeActivity(int userId) {
23496 return PackageManagerService.this.getDefaultHomeActivity(userId);
23500 public ComponentName getSystemUiServiceComponent() {
23501 return ComponentName.unflattenFromString(mContext.getResources().getString(
23502 com.android.internal.R.string.config_systemUIServiceComponent));
23506 public void setDeviceAndProfileOwnerPackages(
23507 int deviceOwnerUserId, String deviceOwnerPackage,
23508 SparseArray<String> profileOwnerPackages) {
23509 mProtectedPackages.setDeviceAndProfileOwnerPackages(
23510 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
23512 final ArraySet<Integer> usersWithPoOrDo = new ArraySet<>();
23513 if (deviceOwnerPackage != null) {
23514 usersWithPoOrDo.add(deviceOwnerUserId);
23516 final int sz = profileOwnerPackages.size();
23517 for (int i = 0; i < sz; i++) {
23518 if (profileOwnerPackages.valueAt(i) != null) {
23519 usersWithPoOrDo.add(profileOwnerPackages.keyAt(i));
23525 public void setDeviceOwnerProtectedPackages(List<String> packageNames) {
23526 mProtectedPackages.setDeviceOwnerProtectedPackages(packageNames);
23530 public boolean isPackageDataProtected(int userId, String packageName) {
23531 return mProtectedPackages.isPackageDataProtected(userId, packageName);
23535 public boolean isPackageStateProtected(String packageName, int userId) {
23536 return mProtectedPackages.isPackageStateProtected(userId, packageName);
23540 public boolean isPackageEphemeral(int userId, String packageName) {
23541 synchronized (mLock) {
23542 final PackageSetting ps = mSettings.mPackages.get(packageName);
23543 return ps != null ? ps.getInstantApp(userId) : false;
23548 public boolean wasPackageEverLaunched(String packageName, int userId) {
23549 synchronized (mLock) {
23550 return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23555 public boolean isEnabledAndMatches(ParsedMainComponent component, int flags, int userId) {
23556 synchronized (mLock) {
23557 AndroidPackage pkg = getPackage(component.getPackageName());
23558 return mSettings.isEnabledAndMatchLPr(pkg, component, flags, userId);
23563 public boolean userNeedsBadging(int userId) {
23564 synchronized (mLock) {
23565 return PackageManagerService.this.userNeedsBadging(userId);
23570 public String getNameForUid(int uid) {
23571 return PackageManagerService.this.getNameForUid(uid);
23575 public boolean setInstalled(AndroidPackage pkg, @UserIdInt int userId,
23576 boolean installed) {
23577 synchronized (mLock) {
23578 final PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
23579 if (ps.getInstalled(userId) != installed) {
23580 ps.setInstalled(installed, userId);
23588 public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23589 Intent origIntent, String resolvedType, String callingPackage,
23590 @Nullable String callingFeatureId, boolean isRequesterInstantApp,
23591 Bundle verificationBundle, int userId) {
23592 PackageManagerService.this.requestInstantAppResolutionPhaseTwo(responseObj, origIntent,
23593 resolvedType, callingPackage, callingFeatureId, isRequesterInstantApp,
23594 verificationBundle, userId);
23598 public void grantImplicitAccess(int userId, Intent intent,
23599 int recipientAppId, int visibleUid, boolean direct) {
23600 synchronized (mLock) {
23601 final AndroidPackage visiblePackage = getPackage(visibleUid);
23602 final int recipientUid = UserHandle.getUid(userId, recipientAppId);
23603 if (visiblePackage == null || getPackage(recipientUid) == null) {
23607 final boolean instantApp =
23608 isInstantAppInternal(visiblePackage.getPackageName(), userId, visibleUid);
23611 // if the interaction that lead to this granting access to an instant app
23612 // was indirect (i.e.: URI permission grant), do not actually execute the
23616 mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23617 recipientAppId, UserHandle.getAppId(visibleUid) /*instantAppId*/);
23619 mAppsFilter.grantImplicitAccess(recipientUid, visibleUid);
23625 public boolean isInstantAppInstallerComponent(ComponentName component) {
23626 synchronized (mLock) {
23627 return mInstantAppInstallerActivity != null
23628 && mInstantAppInstallerActivity.getComponentName().equals(component);
23633 public void pruneInstantApps() {
23634 mInstantAppRegistry.pruneInstantApps();
23638 public String getSetupWizardPackageName() {
23639 return mSetupWizardPackage;
23642 public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23643 if (policy != null) {
23644 mExternalSourcesPolicy = policy;
23649 public boolean isPackagePersistent(String packageName) {
23650 synchronized (mLock) {
23651 AndroidPackage pkg = mPackages.get(packageName);
23652 return pkg != null && pkg.isSystem() && pkg.isPersistent();
23657 public boolean isLegacySystemApp(AndroidPackage pkg) {
23658 synchronized (mLock) {
23659 final PackageSetting ps = getPackageSetting(pkg.getPackageName());
23660 return mPromoteSystemApps
23662 && mExistingSystemPackages.contains(ps.name);
23667 public List<PackageInfo> getOverlayPackages(int userId) {
23668 final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
23669 synchronized (mLock) {
23670 for (AndroidPackage p : mPackages.values()) {
23671 if (p.getOverlayTarget() != null) {
23672 PackageInfo pkg = generatePackageInfo(getPackageSetting(p.getPackageName()),
23675 overlayPackages.add(pkg);
23680 return overlayPackages;
23684 public List<String> getTargetPackageNames(int userId) {
23685 List<String> targetPackages = new ArrayList<>();
23686 synchronized (mLock) {
23687 for (AndroidPackage p : mPackages.values()) {
23688 if (p.getOverlayTarget() == null) {
23689 targetPackages.add(p.getPackageName());
23693 return targetPackages;
23697 public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
23698 @Nullable List<String> overlayPackageNames,
23699 @NonNull Collection<String> outUpdatedPackageNames) {
23700 synchronized (mLock) {
23701 final AndroidPackage targetPkg = mPackages.get(targetPackageName);
23702 if (targetPackageName == null || targetPkg == null) {
23703 Slog.e(TAG, "failed to find package " + targetPackageName);
23706 ArrayList<String> overlayPaths = null;
23707 if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
23708 final int N = overlayPackageNames.size();
23709 overlayPaths = new ArrayList<>(N);
23710 for (int i = 0; i < N; i++) {
23711 final String packageName = overlayPackageNames.get(i);
23712 final AndroidPackage pkg = mPackages.get(packageName);
23714 Slog.e(TAG, "failed to find package " + packageName);
23717 overlayPaths.add(pkg.getBaseCodePath());
23721 ArraySet<String> updatedPackageNames = null;
23722 if (targetPkg.getLibraryNames() != null) {
23723 // Set the overlay paths for dependencies of the shared library.
23724 updatedPackageNames = new ArraySet<>();
23725 for (String libName : targetPkg.getLibraryNames()) {
23726 final SharedLibraryInfo info = getSharedLibraryInfoLPr(libName,
23727 SharedLibraryInfo.VERSION_UNDEFINED);
23728 if (info == null) {
23731 final List<VersionedPackage> dependents = getPackagesUsingSharedLibraryLPr(
23733 if (dependents == null) {
23736 for (VersionedPackage dependent : dependents) {
23737 final PackageSetting ps = mSettings.mPackages.get(
23738 dependent.getPackageName());
23742 ps.setOverlayPathsForLibrary(libName, overlayPaths, userId);
23743 updatedPackageNames.add(dependent.getPackageName());
23748 final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
23749 ps.setOverlayPaths(overlayPaths, userId);
23751 outUpdatedPackageNames.add(targetPackageName);
23752 if (updatedPackageNames != null) {
23753 outUpdatedPackageNames.addAll(updatedPackageNames);
23761 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23762 int flags, int privateResolveFlags, int userId, boolean resolveForStart,
23763 int filterCallingUid) {
23764 return resolveIntentInternal(
23765 intent, resolvedType, flags, privateResolveFlags, userId, resolveForStart,
23770 public ResolveInfo resolveService(Intent intent, String resolvedType,
23771 int flags, int userId, int callingUid) {
23772 return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
23776 public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
23777 return PackageManagerService.this.resolveContentProviderInternal(
23778 name, flags, userId);
23782 public void addIsolatedUid(int isolatedUid, int ownerUid) {
23783 synchronized (mLock) {
23784 mIsolatedOwners.put(isolatedUid, ownerUid);
23789 public void removeIsolatedUid(int isolatedUid) {
23790 synchronized (mLock) {
23791 mIsolatedOwners.delete(isolatedUid);
23796 public int getUidTargetSdkVersion(int uid) {
23797 synchronized (mLock) {
23798 return getUidTargetSdkVersionLockedLPr(uid);
23803 public int getPackageTargetSdkVersion(String packageName) {
23804 synchronized (mLock) {
23805 return getPackageTargetSdkVersionLockedLPr(packageName);
23810 public boolean canAccessInstantApps(int callingUid, int userId) {
23811 return PackageManagerService.this.canViewInstantApps(callingUid, userId);
23815 public boolean canAccessComponent(int callingUid, ComponentName component, int userId) {
23816 synchronized (mLock) {
23817 final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
23818 return ps != null && !PackageManagerService.this.shouldFilterApplicationLocked(
23819 ps, callingUid, component, TYPE_UNKNOWN, userId);
23824 public boolean hasInstantApplicationMetadata(String packageName, int userId) {
23825 synchronized (mLock) {
23826 return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
23831 public void notifyPackageUse(String packageName, int reason) {
23832 synchronized (mLock) {
23833 PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
23838 public SparseArray<String> getAppsWithSharedUserIds() {
23839 synchronized (mLock) {
23840 return getAppsWithSharedUserIdsLocked();
23846 public String[] getSharedUserPackagesForPackage(String packageName, int userId) {
23847 synchronized (mLock) {
23848 return getSharedUserPackagesForPackageLocked(packageName, userId);
23853 public ArrayMap<String, ProcessInfo> getProcessesForUid(int uid) {
23854 synchronized (mLock) {
23855 return getProcessesForUidLocked(uid);
23860 public int[] getPermissionGids(String permissionName, int userId) {
23861 synchronized (mLock) {
23862 return getPermissionGidsLocked(permissionName, userId);
23867 public boolean isOnlyCoreApps() {
23868 return PackageManagerService.this.isOnlyCoreApps();
23872 public void freeStorage(String volumeUuid, long bytes, int storageFlags)
23873 throws IOException {
23874 PackageManagerService.this.freeStorage(volumeUuid, bytes, storageFlags);
23878 public void forEachPackage(Consumer<AndroidPackage> actionLocked) {
23879 PackageManagerService.this.forEachPackage(actionLocked);
23883 public void forEachPackageSetting(Consumer<PackageSetting> actionLocked) {
23884 synchronized (mLock) {
23885 for (int index = 0; index < mSettings.mPackages.size(); index++) {
23886 actionLocked.accept(mSettings.mPackages.valueAt(index));
23892 public void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> actionLocked,
23893 @UserIdInt int userId) {
23894 PackageManagerService.this.forEachInstalledPackage(actionLocked, userId);
23898 public ArraySet<String> getEnabledComponents(String packageName, int userId) {
23899 synchronized (mLock) {
23900 PackageSetting setting = mSettings.getPackageLPr(packageName);
23901 if (setting == null) {
23902 return new ArraySet<>();
23904 return setting.getEnabledComponents(userId);
23909 public ArraySet<String> getDisabledComponents(String packageName, int userId) {
23910 synchronized (mLock) {
23911 PackageSetting setting = mSettings.getPackageLPr(packageName);
23912 if (setting == null) {
23913 return new ArraySet<>();
23915 return setting.getDisabledComponents(userId);
23920 public @PackageManager.EnabledState int getApplicationEnabledState(
23921 String packageName, int userId) {
23922 synchronized (mLock) {
23923 PackageSetting setting = mSettings.getPackageLPr(packageName);
23924 if (setting == null) {
23925 return COMPONENT_ENABLED_STATE_DEFAULT;
23927 return setting.getEnabled(userId);
23932 public void setEnableRollbackCode(int token, int enableRollbackCode) {
23933 PackageManagerService.this.setEnableRollbackCode(token, enableRollbackCode);
23937 * Ask the package manager to compile layouts in the given package.
23940 public boolean compileLayouts(String packageName) {
23941 AndroidPackage pkg;
23942 synchronized (mLock) {
23943 pkg = mPackages.get(packageName);
23948 return mArtManagerService.compileLayouts(pkg);
23952 public void finishPackageInstall(int token, boolean didLaunch) {
23953 PackageManagerService.this.finishPackageInstall(token, didLaunch);
23958 public String removeLegacyDefaultBrowserPackageName(int userId) {
23959 synchronized (mLock) {
23960 return mSettings.removeDefaultBrowserPackageNameLPw(userId);
23965 public boolean isApexPackage(String packageName) {
23966 return PackageManagerService.this.mApexManager.isApexPackage(packageName);
23970 public List<String> getApksInApex(String apexPackageName) {
23971 return PackageManagerService.this.mApexManager.getApksInApex(apexPackageName);
23975 public void uninstallApex(String packageName, long versionCode, int userId,
23976 IntentSender intentSender, int flags) {
23977 final int callerUid = Binder.getCallingUid();
23978 if (callerUid != Process.ROOT_UID && callerUid != Process.SHELL_UID) {
23979 throw new SecurityException("Not allowed to uninstall apexes");
23981 PackageInstallerService.PackageDeleteObserverAdapter adapter =
23982 new PackageInstallerService.PackageDeleteObserverAdapter(
23983 PackageManagerService.this.mContext, intentSender, packageName,
23985 if ((flags & PackageManager.DELETE_ALL_USERS) == 0) {
23986 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
23987 "Can't uninstall an apex for a single user");
23990 final ApexManager am = PackageManagerService.this.mApexManager;
23991 PackageInfo activePackage = am.getPackageInfo(packageName,
23992 ApexManager.MATCH_ACTIVE_PACKAGE);
23993 if (activePackage == null) {
23994 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
23995 packageName + " is not an apex package");
23998 if (versionCode != PackageManager.VERSION_CODE_HIGHEST
23999 && activePackage.getLongVersionCode() != versionCode) {
24000 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
24001 "Active version " + activePackage.getLongVersionCode()
24002 + " is not equal to " + versionCode + "]");
24005 if (!am.uninstallApex(activePackage.applicationInfo.sourceDir)) {
24006 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
24007 "Failed to uninstall apex " + packageName);
24009 adapter.onPackageDeleted(packageName, PackageManager.DELETE_SUCCEEDED,
24015 public void setRuntimePermissionsFingerPrint(@NonNull String fingerPrint,
24016 @UserIdInt int userId) {
24017 synchronized (mLock) {
24018 mSettings.setRuntimePermissionsFingerPrintLPr(fingerPrint, userId);
24023 public void migrateLegacyObbData() {
24025 mInstaller.migrateLegacyObbData();
24026 } catch (Exception e) {
24032 public void writeSettings(boolean async) {
24033 synchronized (mLock) {
24035 scheduleWriteSettingsLocked();
24037 mSettings.writeLPr();
24043 public void writePermissionSettings(int[] userIds, boolean async) {
24044 synchronized (mLock) {
24045 for (int userId : userIds) {
24046 mSettings.writeRuntimePermissionsForUserLPr(userId, !async);
24052 public boolean isCallerInstallerOfRecord(
24053 @NonNull AndroidPackage pkg, int callingUid) {
24054 synchronized (mLock) {
24058 final PackageSetting packageSetting = getPackageSetting(pkg.getPackageName());
24059 if (packageSetting == null) {
24062 final PackageSetting installerPackageSetting =
24063 mSettings.mPackages.get(packageSetting.installSource.installerPackageName);
24064 return installerPackageSetting != null
24065 && UserHandle.isSameApp(installerPackageSetting.appId, callingUid);
24070 public boolean areDefaultRuntimePermissionsGranted(int userId) {
24071 synchronized (mLock) {
24072 return mSettings.areDefaultRuntimePermissionsGrantedLPr(userId);
24077 public void setReadExternalStorageEnforced(boolean enforced) {
24078 synchronized (mLock) {
24079 if (mSettings.mReadExternalStorageEnforced != null
24080 && mSettings.mReadExternalStorageEnforced == enforced) {
24083 mSettings.mReadExternalStorageEnforced = enforced ? Boolean.TRUE : Boolean.FALSE;
24084 mSettings.writeLPr();
24089 public void setIntegrityVerificationResult(int verificationId, int verificationResult) {
24090 final Message msg = mHandler.obtainMessage(INTEGRITY_VERIFICATION_COMPLETE);
24091 msg.arg1 = verificationId;
24092 msg.obj = verificationResult;
24093 mHandler.sendMessage(msg);
24097 public List<String> getMimeGroup(String packageName, String mimeGroup) {
24098 return PackageManagerService.this.getMimeGroup(packageName, mimeGroup);
24102 @GuardedBy("mLock")
24103 private SparseArray<String> getAppsWithSharedUserIdsLocked() {
24104 final SparseArray<String> sharedUserIds = new SparseArray<>();
24105 synchronized (mLock) {
24106 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
24107 sharedUserIds.put(UserHandle.getAppId(setting.userId), setting.name);
24110 return sharedUserIds;
24113 @GuardedBy("mLock")
24115 private String[] getSharedUserPackagesForPackageLocked(String packageName, int userId) {
24116 final PackageSetting packageSetting = mSettings.mPackages.get(packageName);
24117 if (packageSetting == null || !packageSetting.isSharedUser()) {
24118 return EmptyArray.STRING;
24121 ArraySet<PackageSetting> packages = packageSetting.sharedUser.packages;
24122 String[] res = new String[packages.size()];
24123 final Iterator<PackageSetting> it = packages.iterator();
24125 while (it.hasNext()) {
24126 PackageSetting ps = it.next();
24127 if (ps.getInstalled(userId)) {
24128 res[i++] = ps.name;
24131 res = ArrayUtils.trimToSize(res, i);
24132 return res != null ? res : EmptyArray.STRING;
24135 @GuardedBy("mLock")
24136 public ArrayMap<String, ProcessInfo> getProcessesForUidLocked(int uid) {
24137 final int appId = UserHandle.getAppId(uid);
24138 final SettingBase obj = mSettings.getSettingLPr(appId);
24139 if (obj instanceof SharedUserSetting) {
24140 final SharedUserSetting sus = (SharedUserSetting) obj;
24141 return PackageInfoUtils.generateProcessInfo(sus.processes, 0);
24142 } else if (obj instanceof PackageSetting) {
24143 final PackageSetting ps = (PackageSetting) obj;
24144 return PackageInfoUtils.generateProcessInfo(ps.pkg.getProcesses(), 0);
24149 @GuardedBy("mLock")
24150 public int[] getPermissionGidsLocked(String permissionName, int userId) {
24151 BasePermission perm
24152 = mPermissionManager.getPermissionSettings().getPermission(permissionName);
24153 if (perm != null) {
24154 return perm.computeGids(userId);
24160 public int getRuntimePermissionsVersion(@UserIdInt int userId) {
24161 Preconditions.checkArgumentNonnegative(userId);
24162 enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
24163 "getRuntimePermissionVersion");
24164 synchronized (mLock) {
24165 return mSettings.getDefaultRuntimePermissionsVersionLPr(userId);
24170 public void setRuntimePermissionsVersion(int version, @UserIdInt int userId) {
24171 Preconditions.checkArgumentNonnegative(version);
24172 Preconditions.checkArgumentNonnegative(userId);
24173 enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
24174 "setRuntimePermissionVersion");
24175 synchronized (mLock) {
24176 mSettings.setDefaultRuntimePermissionsVersionLPr(version, userId);
24180 private void enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
24181 @NonNull String message) {
24182 if (mContext.checkCallingOrSelfPermission(
24183 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY)
24184 != PackageManager.PERMISSION_GRANTED
24185 && mContext.checkCallingOrSelfPermission(
24186 Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS)
24187 != PackageManager.PERMISSION_GRANTED) {
24188 throw new SecurityException(message + " requires "
24189 + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " or "
24190 + Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS);
24195 public PackageSetting getPackageSetting(String packageName) {
24196 return getPackageSettingInternal(packageName, Binder.getCallingUid());
24199 private PackageSetting getPackageSettingInternal(String packageName, int callingUid) {
24200 synchronized (mLock) {
24201 packageName = resolveInternalPackageNameInternalLocked(
24202 packageName, PackageManager.VERSION_CODE_HIGHEST, callingUid);
24203 return mSettings.mPackages.get(packageName);
24207 void forEachPackage(Consumer<AndroidPackage> actionLocked) {
24208 synchronized (mLock) {
24209 int numPackages = mPackages.size();
24210 for (int i = 0; i < numPackages; i++) {
24211 actionLocked.accept(mPackages.valueAt(i));
24216 void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> actionLocked,
24217 @UserIdInt int userId) {
24218 synchronized (mLock) {
24219 int numPackages = mPackages.size();
24220 for (int i = 0; i < numPackages; i++) {
24221 AndroidPackage pkg = mPackages.valueAt(i);
24222 PackageSetting setting = mSettings.getPackageLPr(pkg.getPackageName());
24223 if (setting == null || !setting.getInstalled(userId)) {
24226 actionLocked.accept(pkg);
24231 boolean isHistoricalPackageUsageAvailable() {
24232 return mPackageUsage.isHistoricalPackageUsageAvailable();
24236 * Return a <b>copy</b> of the collection of packages known to the package manager.
24237 * @return A copy of the values of mPackages.
24239 Collection<AndroidPackage> getPackages() {
24240 synchronized (mLock) {
24241 return new ArrayList<>(mPackages.values());
24246 * Logs process start information (including base APK hash) to the security log.
24250 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
24251 String apkFile, int pid) {
24252 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24255 if (!SecurityLog.isLoggingEnabled()) {
24258 Bundle data = new Bundle();
24259 data.putLong("startTimestamp", System.currentTimeMillis());
24260 data.putString("processName", processName);
24261 data.putInt("uid", uid);
24262 data.putString("seinfo", seinfo);
24263 data.putString("apkFile", apkFile);
24264 data.putInt("pid", pid);
24265 Message msg = mProcessLoggingHandler.obtainMessage(
24266 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
24268 mProcessLoggingHandler.sendMessage(msg);
24271 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
24272 return mCompilerStats.getPackageStats(pkgName);
24275 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(AndroidPackage pkg) {
24276 return getOrCreateCompilerPackageStats(pkg.getPackageName());
24279 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
24280 return mCompilerStats.getOrCreatePackageStats(pkgName);
24283 public void deleteCompilerPackageStats(String pkgName) {
24284 mCompilerStats.deletePackageStats(pkgName);
24288 public int getInstallReason(String packageName, int userId) {
24289 final int callingUid = Binder.getCallingUid();
24290 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24291 true /* requireFullPermission */, false /* checkShell */,
24292 "get install reason");
24293 synchronized (mLock) {
24294 final PackageSetting ps = mSettings.mPackages.get(packageName);
24295 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
24296 return PackageManager.INSTALL_REASON_UNKNOWN;
24299 return ps.getInstallReason(userId);
24302 return PackageManager.INSTALL_REASON_UNKNOWN;
24306 public boolean canRequestPackageInstalls(String packageName, int userId) {
24307 return canRequestPackageInstallsInternal(packageName, 0, userId,
24308 true /* throwIfPermNotDeclared*/);
24311 private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
24312 boolean throwIfPermNotDeclared) {
24313 int callingUid = Binder.getCallingUid();
24314 int uid = getPackageUid(packageName, 0, userId);
24315 if (callingUid != uid && callingUid != Process.ROOT_UID
24316 && callingUid != Process.SYSTEM_UID) {
24317 throw new SecurityException(
24318 "Caller uid " + callingUid + " does not own package " + packageName);
24320 ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
24321 if (info == null) {
24324 if (info.targetSdkVersion < Build.VERSION_CODES.O) {
24327 if (isInstantApp(packageName, userId)) {
24330 String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
24331 String[] packagesDeclaringPermission =
24332 mPermissionManager.getAppOpPermissionPackages(appOpPermission, callingUid);
24333 if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
24334 if (throwIfPermNotDeclared) {
24335 throw new SecurityException("Need to declare " + appOpPermission
24336 + " to call this api");
24338 Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
24342 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)
24343 || mUserManager.hasUserRestriction(
24344 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, userId)) {
24347 if (mExternalSourcesPolicy != null) {
24348 int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
24349 return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
24355 public ComponentName getInstantAppResolverSettingsComponent() {
24356 return mInstantAppResolverSettingsComponent;
24360 public ComponentName getInstantAppInstallerComponent() {
24361 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24364 return mInstantAppInstallerActivity == null
24365 ? null : mInstantAppInstallerActivity.getComponentName();
24369 public String getInstantAppAndroidId(String packageName, int userId) {
24370 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
24371 "getInstantAppAndroidId");
24372 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
24373 true /* requireFullPermission */, false /* checkShell */,
24374 "getInstantAppAndroidId");
24375 // Make sure the target is an Instant App.
24376 if (!isInstantApp(packageName, userId)) {
24379 synchronized (mLock) {
24380 return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
24384 boolean canHaveOatDir(String packageName) {
24385 synchronized (mLock) {
24386 AndroidPackage p = mPackages.get(packageName);
24387 PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
24388 if (p == null || pkgSetting == null) {
24391 return AndroidPackageUtils.canHaveOatDir(p,
24392 pkgSetting.getPkgState().isUpdatedSystemApp());
24396 private String getOatDir(AndroidPackage pkg, @NonNull PackageSetting pkgSetting) {
24397 if (!AndroidPackageUtils.canHaveOatDir(pkg,
24398 pkgSetting.getPkgState().isUpdatedSystemApp())) {
24401 File codePath = new File(pkg.getCodePath());
24402 if (codePath.isDirectory()) {
24403 return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
24408 void deleteOatArtifactsOfPackage(String packageName) {
24409 final String[] instructionSets;
24410 final List<String> codePaths;
24411 final String oatDir;
24412 final AndroidPackage pkg;
24413 final PackageSetting pkgSetting;
24414 synchronized (mLock) {
24415 pkg = mPackages.get(packageName);
24416 pkgSetting = mSettings.getPackageLPr(packageName);
24418 instructionSets = getAppDexInstructionSets(
24419 AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting),
24420 AndroidPackageUtils.getSecondaryCpuAbi(pkg, pkgSetting));
24421 codePaths = AndroidPackageUtils.getAllCodePaths(pkg);
24422 oatDir = getOatDir(pkg, pkgSetting);
24424 for (String codePath : codePaths) {
24425 for (String isa : instructionSets) {
24427 mInstaller.deleteOdex(codePath, isa, oatDir);
24428 } catch (InstallerException e) {
24429 Log.e(TAG, "Failed deleting oat files for " + codePath, e);
24435 Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
24436 Set<String> unusedPackages = new HashSet<>();
24437 long currentTimeInMillis = System.currentTimeMillis();
24438 synchronized (mLock) {
24439 for (AndroidPackage pkg : mPackages.values()) {
24440 PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
24444 PackageDexUsage.PackageUseInfo packageUseInfo =
24445 getDexManager().getPackageUseInfoOrDefault(pkg.getPackageName());
24446 if (PackageManagerServiceUtils
24447 .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
24448 downgradeTimeThresholdMillis, packageUseInfo,
24449 ps.getPkgState().getLatestPackageUseTimeInMills(),
24450 ps.getPkgState().getLatestForegroundPackageUseTimeInMills())) {
24451 unusedPackages.add(pkg.getPackageName());
24455 return unusedPackages;
24459 public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
24461 final int callingUid = Binder.getCallingUid();
24462 final int callingAppId = UserHandle.getAppId(callingUid);
24464 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24465 true /*requireFullPermission*/, true /*checkShell*/, "setHarmfulAppInfo");
24467 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
24468 checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
24469 throw new SecurityException("Caller must have the "
24470 + SET_HARMFUL_APP_WARNINGS + " permission.");
24473 synchronized (mLock) {
24474 mSettings.setHarmfulAppWarningLPw(packageName, warning, userId);
24475 scheduleWritePackageRestrictionsLocked(userId);
24481 public CharSequence getHarmfulAppWarning(@NonNull String packageName, int userId) {
24482 final int callingUid = Binder.getCallingUid();
24483 final int callingAppId = UserHandle.getAppId(callingUid);
24485 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24486 true /*requireFullPermission*/, true /*checkShell*/, "getHarmfulAppInfo");
24488 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
24489 checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
24490 throw new SecurityException("Caller must have the "
24491 + SET_HARMFUL_APP_WARNINGS + " permission.");
24494 synchronized (mLock) {
24495 return mSettings.getHarmfulAppWarningLPr(packageName, userId);
24500 public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) {
24501 final int callingUid = Binder.getCallingUid();
24502 final int callingAppId = UserHandle.getAppId(callingUid);
24504 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24505 false /*requireFullPermission*/, true /*checkShell*/, "isPackageStateProtected");
24507 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID
24508 && checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid) != PERMISSION_GRANTED) {
24509 throw new SecurityException("Caller must have the "
24510 + MANAGE_DEVICE_ADMINS + " permission.");
24513 return mProtectedPackages.isPackageStateProtected(userId, packageName);
24517 public void sendDeviceCustomizationReadyBroadcast() {
24518 mContext.enforceCallingPermission(Manifest.permission.SEND_DEVICE_CUSTOMIZATION_READY,
24519 "sendDeviceCustomizationReadyBroadcast");
24521 final long ident = Binder.clearCallingIdentity();
24523 final Intent intent = new Intent(Intent.ACTION_DEVICE_CUSTOMIZATION_READY);
24524 intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
24525 final IActivityManager am = ActivityManager.getService();
24526 final String[] requiredPermissions = {
24527 Manifest.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY,
24530 am.broadcastIntentWithFeature(null, null, intent, null, null, 0, null, null,
24531 requiredPermissions, android.app.AppOpsManager.OP_NONE, null, false, false,
24532 UserHandle.USER_ALL);
24533 } catch (RemoteException e) {
24534 throw e.rethrowFromSystemServer();
24537 Binder.restoreCallingIdentity(ident);
24541 private void applyMimeGroupChanges(String packageName, String mimeGroup) {
24542 if (mComponentResolver.updateMimeGroup(packageName, mimeGroup)) {
24543 clearPackagePreferredActivities(packageName, UserHandle.USER_ALL);
24546 mPmInternal.writeSettings(false);
24550 public void setMimeGroup(String packageName, String mimeGroup, List<String> mimeTypes) {
24551 boolean changed = mSettings.mPackages.get(packageName)
24552 .setMimeGroup(mimeGroup, mimeTypes);
24555 applyMimeGroupChanges(packageName, mimeGroup);
24560 public void clearMimeGroup(String packageName, String mimeGroup) {
24561 boolean changed = mSettings.mPackages.get(packageName).clearMimeGroup(mimeGroup);
24564 applyMimeGroupChanges(packageName, mimeGroup);
24569 public List<String> getMimeGroup(String packageName, String mimeGroup) {
24570 return mSettings.mPackages.get(packageName).getMimeGroup(mimeGroup);
24573 static class ActiveInstallSession {
24574 private final String mPackageName;
24575 private final File mStagedDir;
24576 private final IPackageInstallObserver2 mObserver;
24577 private final int mSessionId;
24578 private final PackageInstaller.SessionParams mSessionParams;
24579 private final int mInstallerUid;
24580 @NonNull private final InstallSource mInstallSource;
24581 private final UserHandle mUser;
24582 private final SigningDetails mSigningDetails;
24584 ActiveInstallSession(String packageName, File stagedDir, IPackageInstallObserver2 observer,
24585 int sessionId, PackageInstaller.SessionParams sessionParams, int installerUid,
24586 InstallSource installSource, UserHandle user, SigningDetails signingDetails) {
24587 mPackageName = packageName;
24588 mStagedDir = stagedDir;
24589 mObserver = observer;
24590 mSessionId = sessionId;
24591 mSessionParams = sessionParams;
24592 mInstallerUid = installerUid;
24593 mInstallSource = Preconditions.checkNotNull(installSource);
24595 mSigningDetails = signingDetails;
24598 public String getPackageName() {
24599 return mPackageName;
24602 public File getStagedDir() {
24606 public IPackageInstallObserver2 getObserver() {
24610 public int getSessionId() {
24614 public PackageInstaller.SessionParams getSessionParams() {
24615 return mSessionParams;
24618 public int getInstallerUid() {
24619 return mInstallerUid;
24623 public InstallSource getInstallSource() {
24624 return mInstallSource;
24627 public UserHandle getUser() {
24631 public SigningDetails getSigningDetails() {
24632 return mSigningDetails;
24637 interface PackageSender {
24639 * @param userIds User IDs where the action occurred on a full application
24640 * @param instantUserIds User IDs where the action occurred on an instant application
24642 void sendPackageBroadcast(final String action, final String pkg,
24643 final Bundle extras, final int flags, final String targetPkg,
24644 final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds);
24645 void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
24646 boolean includeStopped, int appId, int[] userIds, int[] instantUserIds);
24647 void notifyPackageAdded(String packageName, int uid);
24648 void notifyPackageChanged(String packageName, int uid);
24649 void notifyPackageRemoved(String packageName, int uid);