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, pkgSetting);
11787 if (pkg.getPackageName().equals("android")) {
11788 synchronized (mLock) {
11789 // Set up information for our fall-back user intent resolution activity.
11790 mPlatformPackage = pkg;
11792 // The instance stored in PackageManagerService is special cased to be non-user
11793 // specific, so initialize all the needed fields here.
11794 mAndroidApplication = pkg.toAppInfoWithoutState();
11795 mAndroidApplication.flags = PackageInfoUtils.appInfoFlags(pkg, pkgSetting);
11796 mAndroidApplication.privateFlags =
11797 PackageInfoUtils.appInfoPrivateFlags(pkg, pkgSetting);
11798 mAndroidApplication.initForUser(UserHandle.USER_SYSTEM);
11800 if (!mResolverReplaced) {
11801 mResolveActivity.applicationInfo = mAndroidApplication;
11802 mResolveActivity.name = ResolverActivity.class.getName();
11803 mResolveActivity.packageName = mAndroidApplication.packageName;
11804 mResolveActivity.processName = "system:ui";
11805 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11806 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
11807 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
11808 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
11809 mResolveActivity.exported = true;
11810 mResolveActivity.enabled = true;
11811 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
11812 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
11813 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
11814 | ActivityInfo.CONFIG_SCREEN_LAYOUT
11815 | ActivityInfo.CONFIG_ORIENTATION
11816 | ActivityInfo.CONFIG_KEYBOARD
11817 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
11818 mResolveInfo.activityInfo = mResolveActivity;
11819 mResolveInfo.priority = 0;
11820 mResolveInfo.preferredOrder = 0;
11821 mResolveInfo.match = 0;
11822 mResolveComponentName = new ComponentName(
11823 mAndroidApplication.packageName, mResolveActivity.name);
11828 ArrayList<AndroidPackage> clientLibPkgs = null;
11830 synchronized (mLock) {
11831 if (!ArrayUtils.isEmpty(reconciledPkg.allowedSharedLibraryInfos)) {
11832 for (SharedLibraryInfo info : reconciledPkg.allowedSharedLibraryInfos) {
11833 commitSharedLibraryInfoLocked(info);
11835 final Map<String, AndroidPackage> combinedSigningDetails =
11836 reconciledPkg.getCombinedAvailablePackages();
11838 // Shared libraries for the package need to be updated.
11839 updateSharedLibrariesLocked(pkg, pkgSetting, null, null,
11840 combinedSigningDetails);
11841 } catch (PackageManagerException e) {
11842 Slog.e(TAG, "updateSharedLibrariesLPr failed: ", e);
11844 // Update all applications that use this library. Skip when booting
11845 // since this will be done after all packages are scaned.
11846 if ((scanFlags & SCAN_BOOTING) == 0) {
11847 clientLibPkgs = updateAllSharedLibrariesLocked(pkg, pkgSetting,
11848 combinedSigningDetails);
11852 if (reconciledPkg.installResult != null) {
11853 reconciledPkg.installResult.libraryConsumers = clientLibPkgs;
11856 if ((scanFlags & SCAN_BOOTING) != 0) {
11857 // No apps can run during boot scan, so they don't need to be frozen
11858 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
11859 // Caller asked to not kill app, so it's probably not frozen
11860 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
11861 // Caller asked us to ignore frozen check for some reason; they
11862 // probably didn't know the package name
11864 // We're doing major surgery on this package, so it better be frozen
11865 // right now to keep it from launching
11866 checkPackageFrozen(pkgName);
11869 // Also need to kill any apps that are dependent on the library.
11870 if (clientLibPkgs != null) {
11871 for (int i=0; i<clientLibPkgs.size(); i++) {
11872 AndroidPackage clientPkg = clientLibPkgs.get(i);
11873 killApplication(clientPkg.getPackageName(),
11874 clientPkg.getUid(), "update lib");
11879 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11881 synchronized (mLock) {
11882 // We don't expect installation to fail beyond this point
11884 // Add the new setting to mSettings
11885 mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11886 // Add the new setting to mPackages
11887 mPackages.put(pkg.getPackageName(), pkg);
11888 if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
11889 mApexManager.registerApkInApex(pkg);
11892 // Add the package's KeySets to the global KeySetManagerService
11893 KeySetManagerService ksms = mSettings.mKeySetManagerService;
11894 ksms.addScannedPackageLPw(pkg);
11896 mComponentResolver.addAllComponents(pkg, chatty);
11897 mAppsFilter.addPackage(pkgSetting, mSettings.mPackages);
11899 // Don't allow ephemeral applications to define new permissions groups.
11900 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11901 Slog.w(TAG, "Permission groups from package " + pkg.getPackageName()
11902 + " ignored: instant apps cannot define new permission groups.");
11904 mPermissionManager.addAllPermissionGroups(pkg, chatty);
11907 // Don't allow ephemeral applications to define new permissions.
11908 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11909 Slog.w(TAG, "Permissions from package " + pkg.getPackageName()
11910 + " ignored: instant apps cannot define new permissions.");
11912 mPermissionManager.addAllPermissions(pkg, chatty);
11915 int collectionSize = ArrayUtils.size(pkg.getInstrumentations());
11916 StringBuilder r = null;
11918 for (i = 0; i < collectionSize; i++) {
11919 ParsedInstrumentation a = pkg.getInstrumentations().get(i);
11920 a.setPackageName(pkg.getPackageName());
11921 mInstrumentation.put(a.getComponentName(), a);
11924 r = new StringBuilder(256);
11928 r.append(a.getName());
11932 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r);
11935 if (!pkg.getProtectedBroadcasts().isEmpty()) {
11936 synchronized (mProtectedBroadcasts) {
11937 mProtectedBroadcasts.addAll(pkg.getProtectedBroadcasts());
11941 if (oldPkg != null) {
11942 // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
11943 // revoke callbacks from this method might need to kill apps which need the
11944 // mPackages lock on a different thread. This would dead lock.
11946 // Hence create a copy of all package names and pass it into
11947 // revokeRuntimePermissionsIfGroupChanged. Only for those permissions might get
11948 // revoked. If a new package is added before the async code runs the permission
11949 // won't be granted yet, hence new packages are no problem.
11950 final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
11952 AsyncTask.execute(() ->
11953 mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg,
11958 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11961 private void setUpCustomResolverActivity(AndroidPackage pkg, PackageSetting pkgSetting) {
11962 synchronized (mLock) {
11963 mResolverReplaced = true;
11965 // The instance created in PackageManagerService is special cased to be non-user
11966 // specific, so initialize all the needed fields here.
11967 ApplicationInfo appInfo = pkg.toAppInfoWithoutState();
11968 appInfo.flags = PackageInfoUtils.appInfoFlags(pkg, pkgSetting);
11969 appInfo.privateFlags =
11970 PackageInfoUtils.appInfoPrivateFlags(pkg, pkgSetting);
11971 appInfo.initForUser(UserHandle.USER_SYSTEM);
11973 // Set up information for custom user intent resolution activity.
11974 mResolveActivity.applicationInfo = appInfo;
11975 mResolveActivity.name = mCustomResolverComponentName.getClassName();
11976 mResolveActivity.packageName = pkg.getPackageName();
11977 mResolveActivity.processName = pkg.getProcessName();
11978 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11979 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11980 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11981 mResolveActivity.theme = 0;
11982 mResolveActivity.exported = true;
11983 mResolveActivity.enabled = true;
11984 mResolveInfo.activityInfo = mResolveActivity;
11985 mResolveInfo.priority = 0;
11986 mResolveInfo.preferredOrder = 0;
11987 mResolveInfo.match = 0;
11988 mResolveComponentName = mCustomResolverComponentName;
11989 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11990 mResolveComponentName);
11994 private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11995 if (installerActivity == null) {
11996 if (DEBUG_INSTANT) {
11997 Slog.d(TAG, "Clear ephemeral installer activity");
11999 mInstantAppInstallerActivity = null;
12003 if (DEBUG_INSTANT) {
12004 Slog.d(TAG, "Set ephemeral installer activity: "
12005 + installerActivity.getComponentName());
12007 // Set up information for ephemeral installer activity
12008 mInstantAppInstallerActivity = installerActivity;
12009 mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
12010 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12011 mInstantAppInstallerActivity.exported = true;
12012 mInstantAppInstallerActivity.enabled = true;
12013 mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
12014 mInstantAppInstallerInfo.priority = 1;
12015 mInstantAppInstallerInfo.preferredOrder = 1;
12016 mInstantAppInstallerInfo.isDefault = true;
12017 mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
12018 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
12021 private void killApplication(String pkgName, @AppIdInt int appId, String reason) {
12022 killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
12025 private void killApplication(String pkgName, @AppIdInt int appId,
12026 @UserIdInt int userId, String reason) {
12027 // Request the ActivityManager to kill the process(only for existing packages)
12028 // so that we do not end up in a confused state while the user is still using the older
12029 // version of the application while the new one gets installed.
12030 final long token = Binder.clearCallingIdentity();
12032 IActivityManager am = ActivityManager.getService();
12035 am.killApplication(pkgName, appId, userId, reason);
12036 } catch (RemoteException e) {
12040 Binder.restoreCallingIdentity(token);
12044 private void removePackageLI(AndroidPackage pkg, boolean chatty) {
12045 // Remove the parent package setting
12046 PackageSetting ps = getPackageSetting(pkg.getPackageName());
12048 removePackageLI(ps.name, chatty);
12049 } else if (DEBUG_REMOVE && chatty) {
12050 Log.d(TAG, "Not removing package " + pkg.getPackageName() + "; mExtras == null");
12054 void removePackageLI(String packageName, boolean chatty) {
12055 if (DEBUG_INSTALL) {
12057 Log.d(TAG, "Removing package " + packageName);
12061 synchronized (mLock) {
12062 final AndroidPackage removedPackage = mPackages.remove(packageName);
12063 if (removedPackage != null) {
12064 cleanPackageDataStructuresLILPw(removedPackage, chatty);
12069 void cleanPackageDataStructuresLILPw(AndroidPackage pkg, boolean chatty) {
12070 mComponentResolver.removeAllComponents(pkg, chatty);
12071 mAppsFilter.removePackage(getPackageSetting(pkg.getPackageName()),
12072 mInjector.getUserManagerInternal().getUserIds(), mSettings.mPackages);
12073 mPermissionManager.removeAllPermissions(pkg, chatty);
12075 final int instrumentationSize = ArrayUtils.size(pkg.getInstrumentations());
12076 StringBuilder r = null;
12078 for (i = 0; i < instrumentationSize; i++) {
12079 ParsedInstrumentation a = pkg.getInstrumentations().get(i);
12080 mInstrumentation.remove(a.getComponentName());
12081 if (DEBUG_REMOVE && chatty) {
12083 r = new StringBuilder(256);
12087 r.append(a.getName());
12091 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
12095 if (pkg.isSystem()) {
12096 // Only system apps can hold shared libraries.
12097 final int libraryNamesSize = pkg.getLibraryNames().size();
12098 for (i = 0; i < libraryNamesSize; i++) {
12099 String name = pkg.getLibraryNames().get(i);
12100 if (removeSharedLibraryLPw(name, 0)) {
12101 if (DEBUG_REMOVE && chatty) {
12103 r = new StringBuilder(256);
12115 // Any package can hold static shared libraries.
12116 if (pkg.getStaticSharedLibName() != null) {
12117 if (removeSharedLibraryLPw(pkg.getStaticSharedLibName(),
12118 pkg.getStaticSharedLibVersion())) {
12119 if (DEBUG_REMOVE && chatty) {
12121 r = new StringBuilder(256);
12125 r.append(pkg.getStaticSharedLibName());
12131 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r);
12136 public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
12137 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
12138 final int[] userIds, int[] instantUserIds) {
12139 mHandler.post(() -> {
12141 final IActivityManager am = ActivityManager.getService();
12142 if (am == null) return;
12143 final int[] resolvedUserIds;
12144 if (userIds == null) {
12145 resolvedUserIds = am.getRunningUserIds();
12147 resolvedUserIds = userIds;
12149 doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
12150 resolvedUserIds, false);
12151 if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
12152 doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
12153 instantUserIds, true);
12155 } catch (RemoteException ex) {
12161 public void notifyPackageAdded(String packageName, int uid) {
12162 final PackageListObserver[] observers;
12163 synchronized (mLock) {
12164 if (mPackageListObservers.size() == 0) {
12167 final PackageListObserver[] observerArray =
12168 new PackageListObserver[mPackageListObservers.size()];
12169 observers = mPackageListObservers.toArray(observerArray);
12171 for (int i = observers.length - 1; i >= 0; --i) {
12172 observers[i].onPackageAdded(packageName, uid);
12177 public void notifyPackageChanged(String packageName, int uid) {
12178 final PackageListObserver[] observers;
12179 synchronized (mLock) {
12180 if (mPackageListObservers.size() == 0) {
12183 final PackageListObserver[] observerArray =
12184 new PackageListObserver[mPackageListObservers.size()];
12185 observers = mPackageListObservers.toArray(observerArray);
12187 for (int i = observers.length - 1; i >= 0; --i) {
12188 observers[i].onPackageChanged(packageName, uid);
12192 private static final Comparator<ProviderInfo> sProviderInitOrderSorter = (p1, p2) -> {
12193 final int v1 = p1.initOrder;
12194 final int v2 = p2.initOrder;
12195 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
12199 public void notifyPackageRemoved(String packageName, int uid) {
12200 final PackageListObserver[] observers;
12201 synchronized (mLock) {
12202 if (mPackageListObservers.size() == 0) {
12205 final PackageListObserver[] observerArray =
12206 new PackageListObserver[mPackageListObservers.size()];
12207 observers = mPackageListObservers.toArray(observerArray);
12209 for (int i = observers.length - 1; i >= 0; --i) {
12210 observers[i].onPackageRemoved(packageName, uid);
12215 * Sends a broadcast for the given action.
12216 * <p>If {@code isInstantApp} is {@code true}, then the broadcast is protected with
12217 * the {@link android.Manifest.permission#ACCESS_INSTANT_APPS} permission. This allows
12218 * the system and applications allowed to see instant applications to receive package
12219 * lifecycle events for instant applications.
12221 private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
12222 int flags, String targetPkg, IIntentReceiver finishedReceiver,
12223 int[] userIds, boolean isInstantApp)
12224 throws RemoteException {
12225 for (int id : userIds) {
12226 final Intent intent = new Intent(action,
12227 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
12228 final String[] requiredPermissions =
12229 isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null;
12230 if (extras != null) {
12231 intent.putExtras(extras);
12233 if (targetPkg != null) {
12234 intent.setPackage(targetPkg);
12236 // Modify the UID when posting to other users
12237 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
12238 if (uid > 0 && UserHandle.getUserId(uid) != id) {
12239 uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
12240 intent.putExtra(Intent.EXTRA_UID, uid);
12242 intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
12243 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
12244 if (DEBUG_BROADCASTS) {
12245 RuntimeException here = new RuntimeException("here");
12246 here.fillInStackTrace();
12247 Slog.d(TAG, "Sending to user " + id + ": "
12248 + intent.toShortString(false, true, false, false)
12249 + " " + intent.getExtras(), here);
12251 am.broadcastIntentWithFeature(null, null, intent, null, finishedReceiver,
12252 0, null, null, requiredPermissions, android.app.AppOpsManager.OP_NONE,
12253 null, finishedReceiver != null, false, id);
12258 * Check if the external storage media is available. This is true if there
12259 * is a mounted external storage medium or if the external storage is
12262 private boolean isExternalMediaAvailable() {
12263 return mMediaMounted || Environment.isExternalStorageEmulated();
12267 * Ensure that the install reason matches what we know about the package installer (e.g. whether
12268 * it is acting on behalf on an enterprise or the user).
12270 * Note that the ordering of the conditionals in this method is important. The checks we perform
12271 * are as follows, in this order:
12273 * 1) If the install is being performed by a system app, we can trust the app to have set the
12274 * install reason correctly. Thus, we pass through the install reason unchanged, no matter
12276 * 2) If the install is being performed by a device or profile owner app, the install reason
12277 * should be enterprise policy. However, we cannot be sure that the device or profile owner
12278 * set the install reason correctly. If the app targets an older SDK version where install
12279 * reasons did not exist yet, or if the app author simply forgot, the install reason may be
12280 * unset or wrong. Thus, we force the install reason to be enterprise policy.
12281 * 3) In all other cases, the install is being performed by a regular app that is neither part
12282 * of the system nor a device or profile owner. We have no reason to believe that this app is
12283 * acting on behalf of the enterprise admin. Thus, we check whether the install reason was
12284 * set to enterprise policy and if so, change it to unknown instead.
12286 private int fixUpInstallReason(String installerPackageName, int installerUid,
12287 int installReason) {
12288 if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
12289 == PERMISSION_GRANTED) {
12290 // If the install is being performed by a system app, we trust that app to have set the
12291 // install reason correctly.
12292 return installReason;
12294 final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(
12295 UserHandle.getUserId(installerUid));
12296 if (ownerPackage != null && ownerPackage.equals(installerPackageName)) {
12297 // If the install is being performed by a device or profile owner, the install
12298 // reason should be enterprise policy.
12299 return PackageManager.INSTALL_REASON_POLICY;
12303 if (installReason == PackageManager.INSTALL_REASON_POLICY) {
12304 // If the install is being performed by a regular app (i.e. neither system app nor
12305 // device or profile owner), we have no reason to believe that the app is acting on
12306 // behalf of an enterprise. If the app set the install reason to enterprise policy,
12307 // change it to unknown instead.
12308 return PackageManager.INSTALL_REASON_UNKNOWN;
12311 // If the install is being performed by a regular app and the install reason was set to any
12312 // value but enterprise policy, leave the install reason unchanged.
12313 return installReason;
12316 void installStage(ActiveInstallSession activeInstallSession) {
12317 if (DEBUG_INSTANT) {
12318 if ((activeInstallSession.getSessionParams().installFlags
12319 & PackageManager.INSTALL_INSTANT_APP) != 0) {
12320 Slog.d(TAG, "Ephemeral install of " + activeInstallSession.getPackageName());
12323 final Message msg = mHandler.obtainMessage(INIT_COPY);
12324 final InstallParams params = new InstallParams(activeInstallSession);
12325 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
12328 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
12329 System.identityHashCode(msg.obj));
12330 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
12331 System.identityHashCode(msg.obj));
12333 mHandler.sendMessage(msg);
12336 void installStage(List<ActiveInstallSession> children)
12337 throws PackageManagerException {
12338 final Message msg = mHandler.obtainMessage(INIT_COPY);
12339 final MultiPackageInstallParams params =
12340 new MultiPackageInstallParams(UserHandle.ALL, children);
12341 params.setTraceMethod("installStageMultiPackage")
12342 .setTraceCookie(System.identityHashCode(params));
12345 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStageMultiPackage",
12346 System.identityHashCode(msg.obj));
12347 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
12348 System.identityHashCode(msg.obj));
12349 mHandler.sendMessage(msg);
12352 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
12354 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
12355 final boolean isInstantApp = pkgSetting.getInstantApp(userId);
12356 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
12357 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
12358 sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
12359 false /*startReceiver*/, pkgSetting.appId, userIds, instantUserIds);
12361 // Send a session commit broadcast
12362 final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
12363 info.installReason = pkgSetting.getInstallReason(userId);
12364 info.appPackageName = packageName;
12365 sendSessionCommitBroadcast(info, userId);
12369 public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
12370 boolean includeStopped, @AppIdInt int appId, int[] userIds, int[] instantUserIds) {
12371 if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
12374 Bundle extras = new Bundle(1);
12375 // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
12376 final int uid = UserHandle.getUid(
12377 (ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId);
12378 extras.putInt(Intent.EXTRA_UID, uid);
12380 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
12381 packageName, extras, 0, null, null, userIds, instantUserIds);
12382 if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
12383 mHandler.post(() -> {
12384 for (int userId : userIds) {
12385 sendBootCompletedBroadcastToSystemApp(
12386 packageName, includeStopped, userId);
12394 * The just-installed/enabled app is bundled on the system, so presumed to be able to run
12395 * automatically without needing an explicit launch.
12396 * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
12398 private void sendBootCompletedBroadcastToSystemApp(
12399 String packageName, boolean includeStopped, int userId) {
12400 // If user is not running, the app didn't miss any broadcast
12401 if (!mUserManager.isUserRunning(userId)) {
12404 final IActivityManager am = ActivityManager.getService();
12406 // Deliver LOCKED_BOOT_COMPLETED first
12407 Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
12408 .setPackage(packageName);
12409 if (includeStopped) {
12410 lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
12412 final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
12413 am.broadcastIntentWithFeature(null, null, lockedBcIntent, null, null, 0, null, null,
12414 requiredPermissions, android.app.AppOpsManager.OP_NONE, null, false, false,
12417 // Deliver BOOT_COMPLETED only if user is unlocked
12418 if (mUserManager.isUserUnlockingOrUnlocked(userId)) {
12419 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
12420 if (includeStopped) {
12421 bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
12423 am.broadcastIntentWithFeature(null, null, bcIntent, null, null, 0, null, null,
12424 requiredPermissions, android.app.AppOpsManager.OP_NONE, null, false, false,
12427 } catch (RemoteException e) {
12428 throw e.rethrowFromSystemServer();
12433 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
12435 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
12436 PackageSetting pkgSetting;
12437 final int callingUid = Binder.getCallingUid();
12438 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
12439 true /* requireFullPermission */, true /* checkShell */,
12440 "setApplicationHiddenSetting for user " + userId);
12442 if (hidden && isPackageDeviceAdmin(packageName, userId)) {
12443 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
12447 long callingId = Binder.clearCallingIdentity();
12449 boolean sendAdded = false;
12450 boolean sendRemoved = false;
12452 synchronized (mLock) {
12453 pkgSetting = mSettings.mPackages.get(packageName);
12454 if (pkgSetting == null) {
12457 if (shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
12460 // Do not allow "android" is being disabled
12461 if ("android".equals(packageName)) {
12462 Slog.w(TAG, "Cannot hide package: android");
12465 // Cannot hide static shared libs as they are considered
12466 // a part of the using app (emulating static linking). Also
12467 // static libs are installed always on internal storage.
12468 AndroidPackage pkg = mPackages.get(packageName);
12469 if (pkg != null && pkg.getStaticSharedLibName() != null) {
12470 Slog.w(TAG, "Cannot hide package: " + packageName
12471 + " providing static shared library: "
12472 + pkg.getStaticSharedLibName());
12475 // Only allow protected packages to hide themselves.
12476 if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
12477 && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
12478 Slog.w(TAG, "Not hiding protected package: " + packageName);
12482 if (pkgSetting.getHidden(userId) != hidden) {
12483 pkgSetting.setHidden(hidden, userId);
12484 mSettings.writePackageRestrictionsLPr(userId);
12486 sendRemoved = true;
12493 sendPackageAddedForUser(packageName, pkgSetting, userId);
12497 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
12499 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
12503 Binder.restoreCallingIdentity(callingId);
12509 public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) {
12510 final int callingUid = Binder.getCallingUid();
12511 PackageManagerServiceUtils
12512 .enforceSystemOrPhoneCaller("setSystemAppHiddenUntilInstalled", callingUid);
12513 synchronized (mLock) {
12514 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
12515 if (pkgSetting == null || !pkgSetting.isSystem()) {
12518 pkgSetting.getPkgState().setHiddenUntilInstalled(hidden);
12519 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(packageName);
12520 if (disabledPs == null) {
12523 disabledPs.getPkgState().setHiddenUntilInstalled(hidden);
12528 public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
12529 final int callingUid = Binder.getCallingUid();
12530 PackageManagerServiceUtils
12531 .enforceSystemOrPhoneCaller("setSystemAppInstallState", callingUid);
12532 synchronized (mLock) {
12533 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
12534 // The target app should always be in system
12535 if (pkgSetting == null || !pkgSetting.isSystem()) {
12538 // Check if the install state is the same
12539 if (pkgSetting.getInstalled(userId) == installed) {
12544 final long callingId = Binder.clearCallingIdentity();
12547 // install the app from uninstalled state
12548 installExistingPackageAsUser(
12551 PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
12552 PackageManager.INSTALL_REASON_DEVICE_SETUP,
12557 // uninstall the app from installed state
12558 deletePackageVersioned(
12559 new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
12560 new LegacyPackageDeleteObserver(null).getBinder(),
12562 PackageManager.DELETE_SYSTEM_APP);
12565 Binder.restoreCallingIdentity(callingId);
12569 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
12571 final PackageRemovedInfo info = new PackageRemovedInfo(this);
12572 info.removedPackage = packageName;
12573 info.installerPackageName = pkgSetting.installSource.installerPackageName;
12574 info.removedUsers = new int[] {userId};
12575 info.broadcastUsers = new int[] {userId};
12576 info.uid = UserHandle.getUid(userId, pkgSetting.appId);
12577 info.sendPackageRemovedBroadcasts(true /*killApp*/);
12580 private void sendDistractingPackagesChanged(String[] pkgList, int[] uidList, int userId,
12581 int distractionFlags) {
12582 final Bundle extras = new Bundle(3);
12583 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
12584 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
12585 extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags);
12586 sendPackageBroadcast(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null, extras,
12587 Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, new int[]{userId}, null);
12590 private void sendPackagesSuspendedForUser(String[] pkgList, int[] uidList, int userId,
12591 boolean suspended) {
12592 final Bundle extras = new Bundle(3);
12593 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
12594 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
12595 sendPackageBroadcast(
12596 suspended ? Intent.ACTION_PACKAGES_SUSPENDED
12597 : Intent.ACTION_PACKAGES_UNSUSPENDED,
12598 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
12599 new int[] {userId}, null);
12603 * Returns true if application is not found or there was an error. Otherwise it returns
12604 * the hidden state of the package for the given user.
12607 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
12608 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
12609 final int callingUid = Binder.getCallingUid();
12610 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
12611 true /* requireFullPermission */, false /* checkShell */,
12612 "getApplicationHidden for user " + userId);
12614 long callingId = Binder.clearCallingIdentity();
12617 synchronized (mLock) {
12618 ps = mSettings.mPackages.get(packageName);
12622 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
12625 return ps.getHidden(userId);
12628 Binder.restoreCallingIdentity(callingId);
12636 public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
12637 int installReason, List<String> whiteListedPermissions) {
12638 return installExistingPackageAsUser(packageName, userId, installFlags, installReason,
12639 whiteListedPermissions, null);
12642 int installExistingPackageAsUser(@Nullable String packageName, @UserIdInt int userId,
12643 @PackageManager.InstallFlags int installFlags,
12644 @PackageManager.InstallReason int installReason,
12645 @Nullable List<String> whiteListedPermissions, @Nullable IntentSender intentSender) {
12646 if (DEBUG_INSTALL) {
12647 Log.v(TAG, "installExistingPackageAsUser package=" + packageName + " userId=" + userId
12648 + " installFlags=" + installFlags + " installReason=" + installReason
12649 + " whiteListedPermissions=" + whiteListedPermissions);
12652 final int callingUid = Binder.getCallingUid();
12653 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES)
12654 != PackageManager.PERMISSION_GRANTED
12655 && mContext.checkCallingOrSelfPermission(
12656 android.Manifest.permission.INSTALL_EXISTING_PACKAGES)
12657 != PackageManager.PERMISSION_GRANTED) {
12658 throw new SecurityException("Neither user " + callingUid + " nor current process has "
12659 + android.Manifest.permission.INSTALL_PACKAGES + ".");
12661 PackageSetting pkgSetting;
12662 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
12663 true /* requireFullPermission */, true /* checkShell */,
12664 "installExistingPackage for user " + userId);
12665 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
12666 return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
12669 long callingId = Binder.clearCallingIdentity();
12671 boolean installed = false;
12672 final boolean instantApp =
12673 (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
12674 final boolean fullApp =
12675 (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
12678 synchronized (mLock) {
12679 pkgSetting = mSettings.mPackages.get(packageName);
12680 if (pkgSetting == null) {
12681 return PackageManager.INSTALL_FAILED_INVALID_URI;
12683 if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
12684 // only allow the existing package to be used if it's installed as a full
12685 // application for at least one user
12686 boolean installAllowed = false;
12687 for (int checkUserId : mUserManager.getUserIds()) {
12688 installAllowed = !pkgSetting.getInstantApp(checkUserId);
12689 if (installAllowed) {
12693 if (!installAllowed) {
12694 return PackageManager.INSTALL_FAILED_INVALID_URI;
12697 if (!pkgSetting.getInstalled(userId)) {
12698 pkgSetting.setInstalled(true, userId);
12699 pkgSetting.setHidden(false, userId);
12700 pkgSetting.setInstallReason(installReason, userId);
12701 mSettings.writePackageRestrictionsLPr(userId);
12702 mSettings.writeKernelMappingLPr(pkgSetting);
12704 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
12705 // upgrade app from instant to full; we don't allow app downgrade
12708 setInstantAppForUser(mInjector, pkgSetting, userId, instantApp, fullApp);
12712 if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS)
12713 != 0 && pkgSetting.pkg != null) {
12714 whiteListedPermissions = pkgSetting.pkg.getRequestedPermissions();
12716 mPermissionManager.setWhitelistedRestrictedPermissions(packageName,
12717 whiteListedPermissions, FLAG_PERMISSION_WHITELIST_INSTALLER, userId);
12719 if (pkgSetting.pkg != null) {
12720 synchronized (mInstallLock) {
12721 // We don't need to freeze for a brand new install
12722 prepareAppDataAfterInstallLIF(pkgSetting.pkg);
12725 sendPackageAddedForUser(packageName, pkgSetting, userId);
12726 synchronized (mLock) {
12727 updateSequenceNumberLP(pkgSetting, new int[]{ userId });
12729 // start async restore with no post-install since we finish install here
12730 PackageInstalledInfo res =
12731 createPackageInstalledInfo(PackageManager.INSTALL_SUCCEEDED);
12732 res.pkg = pkgSetting.pkg;
12733 res.newUsers = new int[]{ userId };
12734 PostInstallData postInstallData = intentSender == null ? null :
12735 new PostInstallData(null, res, () -> onRestoreComplete(res.returnCode,
12736 mContext, intentSender));
12737 restoreAndPostInstall(userId, res, postInstallData);
12740 Binder.restoreCallingIdentity(callingId);
12743 return PackageManager.INSTALL_SUCCEEDED;
12746 static void onRestoreComplete(int returnCode, Context context, IntentSender target) {
12747 Intent fillIn = new Intent();
12748 fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
12749 PackageManager.installStatusToPublicStatus(returnCode));
12751 target.sendIntent(context, 0, fillIn, null, null);
12752 } catch (SendIntentException ignored) {
12756 static void setInstantAppForUser(Injector injector, PackageSetting pkgSetting,
12757 int userId, boolean instantApp, boolean fullApp) {
12758 // no state specified; do nothing
12759 if (!instantApp && !fullApp) {
12762 if (userId != UserHandle.USER_ALL) {
12763 if (instantApp && !pkgSetting.getInstantApp(userId)) {
12764 pkgSetting.setInstantApp(true /*instantApp*/, userId);
12765 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
12766 pkgSetting.setInstantApp(false /*instantApp*/, userId);
12769 for (int currentUserId : injector.getUserManagerInternal().getUserIds()) {
12770 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
12771 pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
12772 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
12773 pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
12779 boolean isUserRestricted(int userId, String restrictionKey) {
12780 Bundle restrictions = mUserManager.getUserRestrictions(userId);
12781 if (restrictions.getBoolean(restrictionKey, false)) {
12782 Log.w(TAG, "User is restricted: " + restrictionKey);
12789 public String[] setDistractingPackageRestrictionsAsUser(String[] packageNames,
12790 int restrictionFlags, int userId) {
12791 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
12792 "setDistractingPackageRestrictionsAsUser");
12794 final int callingUid = Binder.getCallingUid();
12795 if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID
12796 && UserHandle.getUserId(callingUid) != userId) {
12797 throw new SecurityException("Calling uid " + callingUid + " cannot call for user "
12800 Objects.requireNonNull(packageNames, "packageNames cannot be null");
12801 if (restrictionFlags != 0 && !isSuspendAllowedForUser(userId)) {
12802 Slog.w(TAG, "Cannot restrict packages due to restrictions on user " + userId);
12803 return packageNames;
12806 final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
12807 final IntArray changedUids = new IntArray(packageNames.length);
12808 final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
12809 final boolean[] canRestrict = (restrictionFlags != 0) ? canSuspendPackageForUserInternal(
12810 packageNames, userId) : null;
12812 for (int i = 0; i < packageNames.length; i++) {
12813 final String packageName = packageNames[i];
12814 final PackageSetting pkgSetting;
12815 synchronized (mLock) {
12816 pkgSetting = mSettings.mPackages.get(packageName);
12817 if (pkgSetting == null
12818 || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
12819 Slog.w(TAG, "Could not find package setting for package: " + packageName
12820 + ". Skipping...");
12821 unactionedPackages.add(packageName);
12825 if (canRestrict != null && !canRestrict[i]) {
12826 unactionedPackages.add(packageName);
12829 synchronized (mLock) {
12830 final int oldDistractionFlags = pkgSetting.getDistractionFlags(userId);
12831 if (restrictionFlags != oldDistractionFlags) {
12832 pkgSetting.setDistractionFlags(restrictionFlags, userId);
12833 changedPackagesList.add(packageName);
12834 changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
12839 if (!changedPackagesList.isEmpty()) {
12840 final String[] changedPackages = changedPackagesList.toArray(
12841 new String[changedPackagesList.size()]);
12842 sendDistractingPackagesChanged(changedPackages, changedUids.toArray(), userId,
12844 synchronized (mLock) {
12845 scheduleWritePackageRestrictionsLocked(userId);
12848 return unactionedPackages.toArray(new String[0]);
12851 private void enforceCanSetPackagesSuspendedAsUser(String callingPackage, int callingUid,
12852 int userId, String callingMethod) {
12853 if (callingUid == Process.ROOT_UID || callingUid == Process.SYSTEM_UID) {
12857 final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
12858 if (ownerPackage != null) {
12859 final int ownerUid = getPackageUid(ownerPackage, 0, userId);
12860 if (ownerUid == callingUid) {
12865 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
12868 final int packageUid = getPackageUid(callingPackage, 0, userId);
12869 final boolean allowedPackageUid = packageUid == callingUid;
12870 // TODO(b/139383163): remove special casing for shell and enforce INTERACT_ACROSS_USERS_FULL
12871 final boolean allowedShell = callingUid == SHELL_UID
12872 && UserHandle.isSameApp(packageUid, callingUid);
12874 if (!allowedShell && !allowedPackageUid) {
12875 throw new SecurityException("Calling package " + callingPackage + " in user "
12876 + userId + " does not belong to calling uid " + callingUid);
12881 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
12882 PersistableBundle appExtras, PersistableBundle launcherExtras,
12883 SuspendDialogInfo dialogInfo, String callingPackage, int userId) {
12884 final int callingUid = Binder.getCallingUid();
12885 enforceCanSetPackagesSuspendedAsUser(callingPackage, callingUid, userId,
12886 "setPackagesSuspendedAsUser");
12888 if (ArrayUtils.isEmpty(packageNames)) {
12889 return packageNames;
12891 if (suspended && !isSuspendAllowedForUser(userId)) {
12892 Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId);
12893 return packageNames;
12896 final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
12897 final IntArray changedUids = new IntArray(packageNames.length);
12898 final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
12899 final boolean[] canSuspend = suspended ? canSuspendPackageForUserInternal(packageNames,
12902 for (int i = 0; i < packageNames.length; i++) {
12903 final String packageName = packageNames[i];
12904 if (callingPackage.equals(packageName)) {
12905 Slog.w(TAG, "Calling package: " + callingPackage + " trying to "
12906 + (suspended ? "" : "un") + "suspend itself. Ignoring");
12907 unactionedPackages.add(packageName);
12910 final PackageSetting pkgSetting;
12911 synchronized (mLock) {
12912 pkgSetting = mSettings.mPackages.get(packageName);
12913 if (pkgSetting == null
12914 || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
12915 Slog.w(TAG, "Could not find package setting for package: " + packageName
12916 + ". Skipping suspending/un-suspending.");
12917 unactionedPackages.add(packageName);
12921 if (canSuspend != null && !canSuspend[i]) {
12922 unactionedPackages.add(packageName);
12925 boolean packageUnsuspended;
12926 synchronized (mLock) {
12928 pkgSetting.addOrUpdateSuspension(callingPackage, dialogInfo, appExtras,
12929 launcherExtras, userId);
12931 pkgSetting.removeSuspension(callingPackage, userId);
12933 packageUnsuspended = !suspended && !pkgSetting.getSuspended(userId);
12935 if (suspended || packageUnsuspended) {
12936 changedPackagesList.add(packageName);
12937 changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
12941 if (!changedPackagesList.isEmpty()) {
12942 final String[] changedPackages = changedPackagesList.toArray(
12943 new String[changedPackagesList.size()]);
12944 sendPackagesSuspendedForUser(changedPackages, changedUids.toArray(), userId, suspended);
12945 sendMyPackageSuspendedOrUnsuspended(changedPackages, suspended, userId);
12946 synchronized (mLock) {
12947 scheduleWritePackageRestrictionsLocked(userId);
12950 return unactionedPackages.toArray(new String[unactionedPackages.size()]);
12954 public Bundle getSuspendedPackageAppExtras(String packageName, int userId) {
12955 final int callingUid = Binder.getCallingUid();
12956 if (getPackageUid(packageName, 0, userId) != callingUid) {
12957 throw new SecurityException("Calling package " + packageName
12958 + " does not belong to calling uid " + callingUid);
12960 return getSuspendedPackageAppExtrasInternal(packageName, userId);
12963 private Bundle getSuspendedPackageAppExtrasInternal(String packageName, int userId) {
12964 synchronized (mLock) {
12965 final PackageSetting ps = mSettings.mPackages.get(packageName);
12967 throw new IllegalArgumentException("Unknown target package: " + packageName);
12969 final PackageUserState pus = ps.readUserState(userId);
12970 final Bundle allExtras = new Bundle();
12971 if (pus.suspended) {
12972 for (int i = 0; i < pus.suspendParams.size(); i++) {
12973 final PackageUserState.SuspendParams params = pus.suspendParams.valueAt(i);
12974 if (params != null && params.appExtras != null) {
12975 allExtras.putAll(params.appExtras);
12979 return (allExtras.size() > 0) ? allExtras : null;
12983 private void sendMyPackageSuspendedOrUnsuspended(String[] affectedPackages, boolean suspended,
12985 final String action = suspended
12986 ? Intent.ACTION_MY_PACKAGE_SUSPENDED
12987 : Intent.ACTION_MY_PACKAGE_UNSUSPENDED;
12988 mHandler.post(() -> {
12990 final IActivityManager am = ActivityManager.getService();
12992 Slog.wtf(TAG, "IActivityManager null. Cannot send MY_PACKAGE_ "
12993 + (suspended ? "" : "UN") + "SUSPENDED broadcasts");
12996 final int[] targetUserIds = new int[] {userId};
12997 for (String packageName : affectedPackages) {
12998 final Bundle appExtras = suspended
12999 ? getSuspendedPackageAppExtrasInternal(packageName, userId)
13001 final Bundle intentExtras;
13002 if (appExtras != null) {
13003 intentExtras = new Bundle(1);
13004 intentExtras.putBundle(Intent.EXTRA_SUSPENDED_PACKAGE_EXTRAS, appExtras);
13006 intentExtras = null;
13008 doSendBroadcast(am, action, null, intentExtras,
13009 Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, packageName, null,
13010 targetUserIds, false);
13012 } catch (RemoteException ex) {
13013 // Shouldn't happen as AMS is in the same process.
13019 public boolean isPackageSuspendedForUser(String packageName, int userId) {
13020 final int callingUid = Binder.getCallingUid();
13021 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13022 true /* requireFullPermission */, false /* checkShell */,
13023 "isPackageSuspendedForUser for user " + userId);
13024 synchronized (mLock) {
13025 final PackageSetting ps = mSettings.mPackages.get(packageName);
13026 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
13027 throw new IllegalArgumentException("Unknown target package: " + packageName);
13029 return ps.getSuspended(userId);
13033 void unsuspendForSuspendingPackage(String suspendingPackage, int userId) {
13034 final String[] allPackages;
13035 synchronized (mLock) {
13036 allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
13038 removeSuspensionsBySuspendingPackage(allPackages, suspendingPackage::equals, userId);
13042 * Removes any suspensions on given packages that were added by packages that pass the given
13045 * <p> Caller must flush package restrictions if it cares about immediate data consistency.
13047 * @param packagesToChange The packages on which the suspension are to be removed.
13048 * @param suspendingPackagePredicate A predicate identifying the suspending packages whose
13049 * suspensions will be removed.
13050 * @param userId The user for which the changes are taking place.
13052 void removeSuspensionsBySuspendingPackage(String[] packagesToChange,
13053 Predicate<String> suspendingPackagePredicate, int userId) {
13054 final List<String> unsuspendedPackages = new ArrayList<>();
13055 final IntArray unsuspendedUids = new IntArray();
13056 synchronized (mLock) {
13057 for (String packageName : packagesToChange) {
13058 final PackageSetting ps = mSettings.mPackages.get(packageName);
13059 if (ps.getSuspended(userId)) {
13060 ps.removeSuspension(suspendingPackagePredicate, userId);
13061 if (!ps.getSuspended(userId)) {
13062 unsuspendedPackages.add(ps.name);
13063 unsuspendedUids.add(UserHandle.getUid(userId, ps.getAppId()));
13067 scheduleWritePackageRestrictionsLocked(userId);
13069 if (!unsuspendedPackages.isEmpty()) {
13070 final String[] packageArray = unsuspendedPackages.toArray(
13071 new String[unsuspendedPackages.size()]);
13072 sendMyPackageSuspendedOrUnsuspended(packageArray, false, userId);
13073 sendPackagesSuspendedForUser(packageArray, unsuspendedUids.toArray(), userId, false);
13077 void removeAllDistractingPackageRestrictions(int userId) {
13078 final String[] allPackages;
13079 synchronized (mLock) {
13080 allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
13082 PackageManagerService.this.removeDistractingPackageRestrictions(allPackages, userId);
13086 * Removes any {@link android.content.pm.PackageManager.DistractionRestriction restrictions}
13087 * set on given packages.
13089 * <p> Caller must flush package restrictions if it cares about immediate data consistency.
13091 * @param packagesToChange The packages on which restrictions are to be removed.
13092 * @param userId the user for which changes are taking place.
13094 void removeDistractingPackageRestrictions(String[] packagesToChange, int userId) {
13095 final List<String> changedPackages = new ArrayList<>();
13096 final IntArray changedUids = new IntArray();
13097 synchronized (mLock) {
13098 for (String packageName : packagesToChange) {
13099 final PackageSetting ps = mSettings.mPackages.get(packageName);
13100 if (ps.getDistractionFlags(userId) != 0) {
13101 ps.setDistractionFlags(0, userId);
13102 changedPackages.add(ps.name);
13103 changedUids.add(UserHandle.getUid(userId, ps.getAppId()));
13106 if (!changedPackages.isEmpty()) {
13107 final String[] packageArray = changedPackages.toArray(
13108 new String[changedPackages.size()]);
13109 sendDistractingPackagesChanged(packageArray, changedUids.toArray(), userId, 0);
13110 scheduleWritePackageRestrictionsLocked(userId);
13115 private boolean isCallerDeviceOrProfileOwner(int userId) {
13116 final int callingUid = Binder.getCallingUid();
13117 if (callingUid == Process.SYSTEM_UID) {
13120 final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
13121 if (ownerPackage != null) {
13122 return callingUid == getPackageUidInternal(ownerPackage, 0, userId, callingUid);
13127 private boolean isSuspendAllowedForUser(int userId) {
13128 return isCallerDeviceOrProfileOwner(userId)
13129 || (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL, userId)
13130 && !mUserManager.hasUserRestriction(UserManager.DISALLOW_UNINSTALL_APPS, userId));
13134 public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) {
13135 Objects.requireNonNull(packageNames, "packageNames cannot be null");
13136 mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
13137 "getUnsuspendablePackagesForUser");
13138 final int callingUid = Binder.getCallingUid();
13139 if (UserHandle.getUserId(callingUid) != userId) {
13140 throw new SecurityException("Calling uid " + callingUid
13141 + " cannot query getUnsuspendablePackagesForUser for user " + userId);
13143 if (!isSuspendAllowedForUser(userId)) {
13144 Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId);
13145 return packageNames;
13147 final ArraySet<String> unactionablePackages = new ArraySet<>();
13148 final boolean[] canSuspend = canSuspendPackageForUserInternal(packageNames, userId);
13149 for (int i = 0; i < packageNames.length; i++) {
13150 if (!canSuspend[i]) {
13151 unactionablePackages.add(packageNames[i]);
13154 synchronized (mLock) {
13155 final PackageSetting ps = mSettings.mPackages.get(packageNames[i]);
13156 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
13157 Slog.w(TAG, "Could not find package setting for package: " + packageNames[i]);
13158 unactionablePackages.add(packageNames[i]);
13162 return unactionablePackages.toArray(new String[unactionablePackages.size()]);
13166 * Returns an array of booleans, such that the ith boolean denotes whether the ith package can
13167 * be suspended or not.
13169 * @param packageNames The package names to check suspendability for.
13170 * @param userId The user to check in
13171 * @return An array containing results of the checks
13174 private boolean[] canSuspendPackageForUserInternal(@NonNull String[] packageNames, int userId) {
13175 final boolean[] canSuspend = new boolean[packageNames.length];
13176 final boolean isCallerOwner = isCallerDeviceOrProfileOwner(userId);
13177 final long callingId = Binder.clearCallingIdentity();
13179 final String activeLauncherPackageName = getActiveLauncherPackageName(userId);
13180 final String dialerPackageName = mPermissionManager.getDefaultDialer(userId);
13181 for (int i = 0; i < packageNames.length; i++) {
13182 canSuspend[i] = false;
13183 final String packageName = packageNames[i];
13185 if (isPackageDeviceAdmin(packageName, userId)) {
13186 Slog.w(TAG, "Cannot suspend package \"" + packageName
13187 + "\": has an active device admin");
13190 if (packageName.equals(activeLauncherPackageName)) {
13191 Slog.w(TAG, "Cannot suspend package \"" + packageName
13192 + "\": contains the active launcher");
13195 if (packageName.equals(mRequiredInstallerPackage)) {
13196 Slog.w(TAG, "Cannot suspend package \"" + packageName
13197 + "\": required for package installation");
13200 if (packageName.equals(mRequiredUninstallerPackage)) {
13201 Slog.w(TAG, "Cannot suspend package \"" + packageName
13202 + "\": required for package uninstallation");
13205 if (packageName.equals(mRequiredVerifierPackage)) {
13206 Slog.w(TAG, "Cannot suspend package \"" + packageName
13207 + "\": required for package verification");
13210 if (packageName.equals(dialerPackageName)) {
13211 Slog.w(TAG, "Cannot suspend package \"" + packageName
13212 + "\": is the default dialer");
13215 if (packageName.equals(mRequiredPermissionControllerPackage)) {
13216 Slog.w(TAG, "Cannot suspend package \"" + packageName
13217 + "\": required for permissions management");
13220 synchronized (mLock) {
13221 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13222 Slog.w(TAG, "Cannot suspend package \"" + packageName
13223 + "\": protected package");
13226 if (!isCallerOwner && mSettings.getBlockUninstallLPr(userId, packageName)) {
13227 Slog.w(TAG, "Cannot suspend package \"" + packageName
13228 + "\": blocked by admin");
13232 // Cannot suspend static shared libs as they are considered
13233 // a part of the using app (emulating static linking). Also
13234 // static libs are installed always on internal storage.
13235 AndroidPackage pkg = mPackages.get(packageName);
13236 if (pkg != null && pkg.isStaticSharedLibrary()) {
13237 Slog.w(TAG, "Cannot suspend package: " + packageName
13238 + " providing static shared library: "
13239 + pkg.getStaticSharedLibName());
13243 if (PLATFORM_PACKAGE_NAME.equals(packageName)) {
13244 Slog.w(TAG, "Cannot suspend the platform package: " + packageName);
13247 canSuspend[i] = true;
13250 Binder.restoreCallingIdentity(callingId);
13255 private String getActiveLauncherPackageName(int userId) {
13256 Intent intent = new Intent(Intent.ACTION_MAIN);
13257 intent.addCategory(Intent.CATEGORY_HOME);
13258 ResolveInfo resolveInfo = resolveIntent(
13260 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
13261 PackageManager.MATCH_DEFAULT_ONLY,
13264 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
13268 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
13269 mContext.enforceCallingOrSelfPermission(
13270 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13271 "Only package verification agents can verify applications");
13273 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13274 final PackageVerificationResponse response = new PackageVerificationResponse(
13275 verificationCode, Binder.getCallingUid());
13277 msg.obj = response;
13278 mHandler.sendMessage(msg);
13282 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
13283 long millisecondsToDelay) {
13284 mContext.enforceCallingOrSelfPermission(
13285 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13286 "Only package verification agents can extend verification timeouts");
13288 final PackageVerificationState state = mPendingVerification.get(id);
13289 final PackageVerificationResponse response = new PackageVerificationResponse(
13290 verificationCodeAtTimeout, Binder.getCallingUid());
13292 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
13293 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
13295 if (millisecondsToDelay < 0) {
13296 millisecondsToDelay = 0;
13298 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
13299 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
13300 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
13303 if ((state != null) && !state.timeoutExtended()) {
13304 state.extendTimeout();
13306 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13308 msg.obj = response;
13309 mHandler.sendMessageDelayed(msg, millisecondsToDelay);
13313 private void broadcastPackageVerified(int verificationId, Uri packageUri,
13314 int verificationCode, UserHandle user) {
13315 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
13316 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
13317 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
13318 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
13319 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
13321 mContext.sendBroadcastAsUser(intent, user,
13322 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
13325 private ComponentName matchComponentForVerifier(String packageName,
13326 List<ResolveInfo> receivers) {
13327 ActivityInfo targetReceiver = null;
13329 final int NR = receivers.size();
13330 for (int i = 0; i < NR; i++) {
13331 final ResolveInfo info = receivers.get(i);
13332 if (info.activityInfo == null) {
13336 if (packageName.equals(info.activityInfo.packageName)) {
13337 targetReceiver = info.activityInfo;
13342 if (targetReceiver == null) {
13346 return new ComponentName(targetReceiver.packageName, targetReceiver.name);
13349 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
13350 List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
13351 if (pkgInfo.verifiers.length == 0) {
13355 final int N = pkgInfo.verifiers.length;
13356 final List<ComponentName> sufficientVerifiers = new ArrayList<>(N + 1);
13357 for (int i = 0; i < N; i++) {
13358 final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
13360 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
13362 if (comp == null) {
13366 final int verifierUid = getUidForVerifier(verifierInfo);
13367 if (verifierUid == -1) {
13371 if (DEBUG_VERIFY) {
13372 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
13373 + " with the correct signature");
13375 sufficientVerifiers.add(comp);
13376 verificationState.addSufficientVerifier(verifierUid);
13379 return sufficientVerifiers;
13382 private int getUidForVerifier(VerifierInfo verifierInfo) {
13383 synchronized (mLock) {
13384 final AndroidPackage pkg = mPackages.get(verifierInfo.packageName);
13387 } else if (pkg.getSigningDetails().signatures.length != 1) {
13388 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13389 + " has more than one signature; ignoring");
13394 * If the public key of the package's signature does not match
13395 * our expected public key, then this is a different package and
13399 final byte[] expectedPublicKey;
13401 final Signature verifierSig = pkg.getSigningDetails().signatures[0];
13402 final PublicKey publicKey = verifierSig.getPublicKey();
13403 expectedPublicKey = publicKey.getEncoded();
13404 } catch (CertificateException e) {
13408 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
13410 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
13411 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13412 + " does not have the expected public key; ignoring");
13416 return pkg.getUid();
13420 private void setEnableRollbackCode(int token, int enableRollbackCode) {
13421 final Message msg = mHandler.obtainMessage(ENABLE_ROLLBACK_STATUS);
13423 msg.arg2 = enableRollbackCode;
13424 mHandler.sendMessage(msg);
13428 public void finishPackageInstall(int token, boolean didLaunch) {
13429 enforceSystemOrRoot("Only the system is allowed to finish installs");
13431 if (DEBUG_INSTALL) {
13432 Slog.v(TAG, "BM finishing package install for " + token);
13434 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13436 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
13437 mHandler.sendMessage(msg);
13441 * Get the verification agent timeout. Used for both the APK verifier and the
13442 * intent filter verifier.
13444 * @return verification timeout in milliseconds
13446 private long getVerificationTimeout() {
13447 long timeout = Global.getLong(mContext.getContentResolver(),
13448 Global.PACKAGE_VERIFIER_TIMEOUT, DEFAULT_VERIFICATION_TIMEOUT);
13449 // The setting can be used to increase the timeout but not decrease it, since that is
13450 // equivalent to disabling the verifier.
13451 return Math.max(timeout, DEFAULT_VERIFICATION_TIMEOUT);
13455 * Get the default verification agent response code.
13457 * @return default verification response code
13459 private int getDefaultVerificationResponse(UserHandle user) {
13460 if (mUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
13461 return PackageManager.VERIFICATION_REJECT;
13463 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13464 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
13465 DEFAULT_VERIFICATION_RESPONSE);
13469 * Get the default integrity verification response code.
13471 private int getDefaultIntegrityVerificationResponse() {
13472 // We are not exposing this as a user-configurable setting because we don't want to provide
13473 // an easy way to get around the integrity check.
13474 return PackageManager.VERIFICATION_REJECT;
13478 * Check whether or not package verification has been enabled.
13480 * @return true if verification should be performed
13482 private boolean isVerificationEnabled(
13483 PackageInfoLite pkgInfoLite, int userId, int installFlags, int installerUid) {
13484 if (!DEFAULT_VERIFY_ENABLE) {
13488 // Check if installing from ADB
13489 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
13490 if (isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS)) {
13493 // Check if the developer wants to skip verification for ADB installs
13494 if ((installFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0) {
13495 synchronized (mLock) {
13496 if (mSettings.mPackages.get(pkgInfoLite.packageName) == null) {
13497 // Always verify fresh install
13501 // Only skip when apk is debuggable
13502 return !pkgInfoLite.debuggable;
13504 return Global.getInt(mContext.getContentResolver(),
13505 Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0;
13508 if ((installFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0) {
13512 // only when not installed from ADB, skip verification for instant apps when
13513 // the installer and verifier are the same.
13514 if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13515 if (mInstantAppInstallerActivity != null
13516 && mInstantAppInstallerActivity.packageName.equals(
13517 mRequiredVerifierPackage)) {
13519 mInjector.getAppOpsManager()
13520 .checkPackage(installerUid, mRequiredVerifierPackage);
13521 if (DEBUG_VERIFY) {
13522 Slog.i(TAG, "disable verification for instant app");
13525 } catch (SecurityException ignore) { }
13532 * Check whether or not integrity verification has been enabled.
13534 private boolean isIntegrityVerificationEnabled() {
13535 // We are not exposing this as a user-configurable setting because we don't want to provide
13536 // an easy way to get around the integrity check.
13537 return DEFAULT_INTEGRITY_VERIFY_ENABLE;
13541 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
13542 throws RemoteException {
13543 mContext.enforceCallingOrSelfPermission(
13544 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
13545 "Only intentfilter verification agents can verify applications");
13547 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
13548 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
13549 Binder.getCallingUid(), verificationCode, failedDomains);
13551 msg.obj = response;
13552 mHandler.sendMessage(msg);
13556 public int getIntentVerificationStatus(String packageName, int userId) {
13557 final int callingUid = Binder.getCallingUid();
13558 if (UserHandle.getUserId(callingUid) != userId) {
13559 mContext.enforceCallingOrSelfPermission(
13560 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13561 "getIntentVerificationStatus" + userId);
13563 if (getInstantAppPackageName(callingUid) != null) {
13564 return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
13566 synchronized (mLock) {
13567 final PackageSetting ps = mSettings.mPackages.get(packageName);
13569 || shouldFilterApplicationLocked(
13570 ps, callingUid, UserHandle.getUserId(callingUid))) {
13571 return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
13573 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
13578 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
13579 mContext.enforceCallingOrSelfPermission(
13580 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
13582 boolean result = false;
13583 synchronized (mLock) {
13584 final PackageSetting ps = mSettings.mPackages.get(packageName);
13585 if (shouldFilterApplicationLocked(
13586 ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
13589 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
13592 scheduleWritePackageRestrictionsLocked(userId);
13598 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
13599 String packageName) {
13600 final int callingUid = Binder.getCallingUid();
13601 if (getInstantAppPackageName(callingUid) != null) {
13602 return ParceledListSlice.emptyList();
13604 synchronized (mLock) {
13605 final PackageSetting ps = mSettings.mPackages.get(packageName);
13606 if (shouldFilterApplicationLocked(ps, callingUid, UserHandle.getUserId(callingUid))) {
13607 return ParceledListSlice.emptyList();
13609 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
13614 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
13615 if (TextUtils.isEmpty(packageName)) {
13616 return ParceledListSlice.emptyList();
13618 final int callingUid = Binder.getCallingUid();
13619 final int callingUserId = UserHandle.getUserId(callingUid);
13620 synchronized (mLock) {
13621 AndroidPackage pkg = mPackages.get(packageName);
13622 if (pkg == null || ArrayUtils.isEmpty(pkg.getActivities())) {
13623 return ParceledListSlice.emptyList();
13625 final PackageSetting ps = getPackageSetting(pkg.getPackageName());
13627 return ParceledListSlice.emptyList();
13629 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
13630 return ParceledListSlice.emptyList();
13632 final int count = ArrayUtils.size(pkg.getActivities());
13633 ArrayList<IntentFilter> result = new ArrayList<>();
13634 for (int n=0; n<count; n++) {
13635 ParsedActivity activity = pkg.getActivities().get(n);
13636 if (activity.getIntents() != null && activity.getIntents().size() > 0) {
13637 result.addAll(activity.getIntents());
13640 return new ParceledListSlice<IntentFilter>(result) {
13642 protected void writeElement(IntentFilter parcelable, Parcel dest, int callFlags) {
13643 // IntentFilter has final Parcelable methods, so redirect to the subclass
13644 ((ParsedIntentInfo) parcelable).writeIntentInfoToParcel(dest,
13652 * Get the "allow unknown sources" setting.
13654 * @return the current "allow unknown sources" setting
13656 private int getUnknownSourcesSettings() {
13657 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
13658 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
13663 public void setInstallerPackageName(String targetPackage, String installerPackageName) {
13664 final int callingUid = Binder.getCallingUid();
13665 if (getInstantAppPackageName(callingUid) != null) {
13669 synchronized (mLock) {
13670 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
13671 if (targetPackageSetting == null
13672 || shouldFilterApplicationLocked(
13673 targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
13674 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
13677 PackageSetting installerPackageSetting;
13678 if (installerPackageName != null) {
13679 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
13680 if (installerPackageSetting == null) {
13681 throw new IllegalArgumentException("Unknown installer package: "
13682 + installerPackageName);
13685 installerPackageSetting = null;
13688 Signature[] callerSignature;
13689 final int appId = UserHandle.getAppId(callingUid);
13690 final Object obj = mSettings.getSettingLPr(appId);
13692 if (obj instanceof SharedUserSetting) {
13694 ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
13695 } else if (obj instanceof PackageSetting) {
13696 callerSignature = ((PackageSetting)obj).signatures.mSigningDetails.signatures;
13698 throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
13701 throw new SecurityException("Unknown calling UID: " + callingUid);
13704 // Verify: can't set installerPackageName to a package that is
13705 // not signed with the same cert as the caller.
13706 if (installerPackageSetting != null) {
13707 if (compareSignatures(callerSignature,
13708 installerPackageSetting.signatures.mSigningDetails.signatures)
13709 != PackageManager.SIGNATURE_MATCH) {
13710 throw new SecurityException(
13711 "Caller does not have same cert as new installer package "
13712 + installerPackageName);
13716 // Verify: if target already has an installer package, it must
13717 // be signed with the same cert as the caller.
13718 String targetInstallerPackageName =
13719 targetPackageSetting.installSource.installerPackageName;
13720 if (targetInstallerPackageName != null) {
13721 PackageSetting setting = mSettings.mPackages.get(
13722 targetInstallerPackageName);
13723 // If the currently set package isn't valid, then it's always
13724 // okay to change it.
13725 if (setting != null) {
13726 if (compareSignatures(callerSignature,
13727 setting.signatures.mSigningDetails.signatures)
13728 != PackageManager.SIGNATURE_MATCH) {
13729 throw new SecurityException(
13730 "Caller does not have same cert as old installer package "
13731 + targetInstallerPackageName);
13737 targetPackageSetting.setInstallerPackageName(installerPackageName);
13738 mSettings.addInstallerPackageNames(targetPackageSetting.installSource);
13739 mAppsFilter.addPackage(targetPackageSetting, mSettings.mPackages);
13740 scheduleWriteSettingsLocked();
13745 public void setApplicationCategoryHint(String packageName, int categoryHint,
13746 String callerPackageName) {
13747 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
13748 throw new SecurityException("Instant applications don't have access to this method");
13750 mInjector.getAppOpsManager().checkPackage(Binder.getCallingUid(),
13751 callerPackageName);
13752 synchronized (mLock) {
13753 PackageSetting ps = mSettings.mPackages.get(packageName);
13755 throw new IllegalArgumentException("Unknown target package " + packageName);
13757 if (shouldFilterApplicationLocked(
13758 ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
13759 throw new IllegalArgumentException("Unknown target package " + packageName);
13761 if (!Objects.equals(callerPackageName, ps.installSource.installerPackageName)) {
13762 throw new IllegalArgumentException("Calling package " + callerPackageName
13763 + " is not installer for " + packageName);
13766 if (ps.categoryHint != categoryHint) {
13767 ps.categoryHint = categoryHint;
13768 scheduleWriteSettingsLocked();
13773 private void processPendingInstall(final InstallArgs args, final int currentStatus) {
13774 if (args.mMultiPackageInstallParams != null) {
13775 args.mMultiPackageInstallParams.tryProcessInstallRequest(args, currentStatus);
13777 PackageInstalledInfo res = createPackageInstalledInfo(currentStatus);
13778 processInstallRequestsAsync(
13779 res.returnCode == PackageManager.INSTALL_SUCCEEDED,
13780 Collections.singletonList(new InstallRequest(args, res)));
13784 // Queue up an async operation since the package installation may take a little while.
13785 private void processInstallRequestsAsync(boolean success,
13786 List<InstallRequest> installRequests) {
13787 mHandler.post(() -> {
13789 for (InstallRequest request : installRequests) {
13790 request.args.doPreInstall(request.installResult.returnCode);
13792 synchronized (mInstallLock) {
13793 installPackagesTracedLI(installRequests);
13795 for (InstallRequest request : installRequests) {
13796 request.args.doPostInstall(
13797 request.installResult.returnCode, request.installResult.uid);
13800 for (InstallRequest request : installRequests) {
13801 restoreAndPostInstall(request.args.user.getIdentifier(), request.installResult,
13802 new PostInstallData(request.args, request.installResult, null));
13807 private PackageInstalledInfo createPackageInstalledInfo(
13808 int currentStatus) {
13809 PackageInstalledInfo res = new PackageInstalledInfo();
13810 res.setReturnCode(currentStatus);
13813 res.removedInfo = null;
13817 /** @param data Post-install is performed only if this is non-null. */
13818 private void restoreAndPostInstall(
13819 int userId, PackageInstalledInfo res, @Nullable PostInstallData data) {
13820 if (DEBUG_INSTALL) {
13821 Log.v(TAG, "restoreAndPostInstall userId=" + userId + " package=" + res.pkg);
13824 // A restore should be performed at this point if (a) the install
13825 // succeeded, (b) the operation is not an update, and (c) the new
13826 // package has not opted out of backup participation.
13827 final boolean update = res.removedInfo != null
13828 && res.removedInfo.removedPackage != null;
13829 boolean allowBackup = res.pkg != null && res.pkg.isAllowBackup();
13830 boolean doRestore = !update && allowBackup;
13832 // Set up the post-install work request bookkeeping. This will be used
13833 // and cleaned up by the post-install event handling regardless of whether
13834 // there's a restore pass performed. Token values are >= 1.
13836 if (mNextInstallToken < 0) mNextInstallToken = 1;
13837 token = mNextInstallToken++;
13838 if (data != null) {
13839 mRunningInstalls.put(token, data);
13840 } else if (DEBUG_INSTALL) {
13841 Log.v(TAG, "No post-install required for " + token);
13844 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
13846 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
13847 // Pass responsibility to the Backup Manager. It will perform a
13848 // restore if appropriate, then pass responsibility back to the
13849 // Package Manager to run the post-install observer callbacks
13851 if (res.freezer != null) {
13852 res.freezer.close();
13854 doRestore = performBackupManagerRestore(userId, token, res);
13857 // If this is an update to a package that might be potentially downgraded, then we
13858 // need to check with the rollback manager whether there's any userdata that might
13859 // need to be snapshotted or restored for the package.
13861 // TODO(narayan): Get this working for cases where userId == UserHandle.USER_ALL.
13862 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && !doRestore && update) {
13863 doRestore = performRollbackManagerRestore(userId, token, res, data);
13867 // No restore possible, or the Backup Manager was mysteriously not
13868 // available -- just fire the post-install work request directly.
13869 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
13871 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
13873 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
13874 mHandler.sendMessage(msg);
13879 * Perform Backup Manager restore for a given {@link PackageInstalledInfo}.
13880 * Returns whether the restore successfully completed.
13882 private boolean performBackupManagerRestore(int userId, int token, PackageInstalledInfo res) {
13883 IBackupManager bm = IBackupManager.Stub.asInterface(
13884 ServiceManager.getService(Context.BACKUP_SERVICE));
13886 // For backwards compatibility as USER_ALL previously routed directly to USER_SYSTEM
13887 // in the BackupManager. USER_ALL is used in compatibility tests.
13888 if (userId == UserHandle.USER_ALL) {
13889 userId = UserHandle.USER_SYSTEM;
13891 if (DEBUG_INSTALL) {
13892 Log.v(TAG, "token " + token + " to BM for possible restore for user " + userId);
13894 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13896 if (bm.isUserReadyForBackup(userId)) {
13897 bm.restoreAtInstallForUser(
13898 userId, res.pkg.getPackageName(), token);
13900 Slog.w(TAG, "User " + userId + " is not ready. Restore at install "
13901 + "didn't take place.");
13904 } catch (RemoteException e) {
13905 // can't happen; the backup manager is local
13906 } catch (Exception e) {
13907 Slog.e(TAG, "Exception trying to enqueue restore", e);
13911 Slog.e(TAG, "Backup Manager not found!");
13918 * Perform Rollback Manager restore for a given {@link PackageInstalledInfo}.
13919 * Returns whether the restore successfully completed.
13921 private boolean performRollbackManagerRestore(int userId, int token, PackageInstalledInfo res,
13922 PostInstallData data) {
13923 IRollbackManager rm = IRollbackManager.Stub.asInterface(
13924 ServiceManager.getService(Context.ROLLBACK_SERVICE));
13926 final String packageName = res.pkg.getPackageName();
13927 final int[] allUsers = mUserManager.getUserIds();
13928 final int[] installedUsers;
13930 final PackageSetting ps;
13932 long ceDataInode = -1;
13933 synchronized (mSettings) {
13934 ps = mSettings.getPackageLPr(packageName);
13937 ceDataInode = ps.getCeDataInode(userId);
13940 // NOTE: We ignore the user specified in the InstallParam because we know this is
13941 // an update, and hence need to restore data for all installed users.
13942 installedUsers = ps.queryInstalledUsers(allUsers, true);
13945 boolean doSnapshotOrRestore = data != null && data.args != null
13946 && ((data.args.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0
13947 || (data.args.installFlags & PackageManager.INSTALL_REQUEST_DOWNGRADE) != 0);
13949 if (ps != null && doSnapshotOrRestore) {
13950 final String seInfo = AndroidPackageUtils.getSeInfo(res.pkg, ps);
13952 rm.snapshotAndRestoreUserData(packageName, installedUsers, appId, ceDataInode,
13954 } catch (RemoteException re) {
13955 Log.e(TAG, "Error snapshotting/restoring user data: " + re);
13964 * Callback from PackageSettings whenever an app is first transitioned out of the
13965 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if
13966 * the app was "launched" for a restoreAtInstall operation. Therefore we check
13967 * here whether the app is the target of an ongoing install, and only send the
13968 * broadcast immediately if it is not in that state. If it *is* undergoing a restore,
13969 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
13972 void notifyFirstLaunch(final String packageName, final String installerPackage,
13973 final int userId) {
13974 // Serialize this with the rest of the install-process message chain. In the
13975 // restore-at-install case, this Runnable will necessarily run before the
13976 // POST_INSTALL message is processed, so the contents of mRunningInstalls
13977 // are coherent. In the non-restore case, the app has already completed install
13978 // and been launched through some other means, so it is not in a problematic
13979 // state for observers to see the FIRST_LAUNCH signal.
13980 mHandler.post(() -> {
13981 for (int i = 0; i < mRunningInstalls.size(); i++) {
13982 final PostInstallData data = mRunningInstalls.valueAt(i);
13983 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
13986 if (packageName.equals(data.res.pkg.getPackageName())) {
13987 // right package; but is it for the right user?
13988 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
13989 if (userId == data.res.newUsers[uIndex]) {
13990 if (DEBUG_BACKUP) {
13991 Slog.i(TAG, "Package " + packageName
13992 + " being restored so deferring FIRST_LAUNCH");
13999 // didn't find it, so not being restored
14000 if (DEBUG_BACKUP) {
14001 Slog.i(TAG, "Package " + packageName + " sending normal FIRST_LAUNCH");
14003 final boolean isInstantApp = isInstantApp(packageName, userId);
14004 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
14005 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
14006 sendFirstLaunchBroadcast(packageName, installerPackage, userIds, instantUserIds);
14010 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg,
14011 int[] userIds, int[] instantUserIds) {
14012 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14013 installerPkg, null, userIds, instantUserIds);
14016 private abstract class HandlerParams {
14017 /** User handle for the user requesting the information or installation. */
14018 private final UserHandle mUser;
14019 String traceMethod;
14022 HandlerParams(UserHandle user) {
14026 UserHandle getUser() {
14031 * Gets the user handle for the user that the rollback agent should
14032 * use to look up information about this installation when enabling
14035 UserHandle getRollbackUser() {
14036 // The session for packages installed for "all" users is
14037 // associated with the "system" user.
14038 if (mUser == UserHandle.ALL) {
14039 return UserHandle.SYSTEM;
14044 HandlerParams setTraceMethod(String traceMethod) {
14045 this.traceMethod = traceMethod;
14049 HandlerParams setTraceCookie(int traceCookie) {
14050 this.traceCookie = traceCookie;
14054 final void startCopy() {
14055 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14057 handleReturnCode();
14060 abstract void handleStartCopy();
14061 abstract void handleReturnCode();
14064 static class OriginInfo {
14066 * Location where install is coming from, before it has been
14067 * copied/renamed into place. This could be a single monolithic APK
14068 * file, or a cluster directory. This location may be untrusted.
14073 * Flag indicating that {@link #file} has already been staged, meaning downstream users
14074 * don't need to defensively copy the contents.
14076 final boolean staged;
14079 * Flag indicating that {@link #file} is an already installed app that is being moved.
14081 final boolean existing;
14083 final String resolvedPath;
14084 final File resolvedFile;
14086 static OriginInfo fromNothing() {
14087 return new OriginInfo(null, false, false);
14090 static OriginInfo fromUntrustedFile(File file) {
14091 return new OriginInfo(file, false, false);
14094 static OriginInfo fromExistingFile(File file) {
14095 return new OriginInfo(file, false, true);
14098 static OriginInfo fromStagedFile(File file) {
14099 return new OriginInfo(file, true, false);
14102 private OriginInfo(File file, boolean staged, boolean existing) {
14104 this.staged = staged;
14105 this.existing = existing;
14107 if (file != null) {
14108 resolvedPath = file.getAbsolutePath();
14109 resolvedFile = file;
14111 resolvedPath = null;
14112 resolvedFile = null;
14117 static class MoveInfo {
14119 final String fromUuid;
14120 final String toUuid;
14121 final String packageName;
14123 final String seinfo;
14124 final int targetSdkVersion;
14125 final String fromCodePath;
14127 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14128 int appId, String seinfo, int targetSdkVersion,
14129 String fromCodePath) {
14130 this.moveId = moveId;
14131 this.fromUuid = fromUuid;
14132 this.toUuid = toUuid;
14133 this.packageName = packageName;
14134 this.appId = appId;
14135 this.seinfo = seinfo;
14136 this.targetSdkVersion = targetSdkVersion;
14137 this.fromCodePath = fromCodePath;
14141 static class VerificationInfo {
14142 /** A constant used to indicate that a uid value is not present. */
14143 public static final int NO_UID = -1;
14145 /** URI referencing where the package was downloaded from. */
14146 final Uri originatingUri;
14148 /** HTTP referrer URI associated with the originatingURI. */
14149 final Uri referrer;
14151 /** UID of the application that the install request originated from. */
14152 final int originatingUid;
14154 /** UID of application requesting the install */
14155 final int installerUid;
14157 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14158 this.originatingUri = originatingUri;
14159 this.referrer = referrer;
14160 this.originatingUid = originatingUid;
14161 this.installerUid = installerUid;
14166 * Container for a multi-package install which refers to all install sessions and args being
14167 * committed together.
14169 class MultiPackageInstallParams extends HandlerParams {
14171 private int mRet = INSTALL_SUCCEEDED;
14173 private final ArrayList<InstallParams> mChildParams;
14175 private final Map<InstallArgs, Integer> mCurrentState;
14177 MultiPackageInstallParams(
14178 @NonNull UserHandle user,
14179 @NonNull List<ActiveInstallSession> activeInstallSessions)
14180 throws PackageManagerException {
14182 if (activeInstallSessions.size() == 0) {
14183 throw new PackageManagerException("No child sessions found!");
14185 mChildParams = new ArrayList<>(activeInstallSessions.size());
14186 for (int i = 0; i < activeInstallSessions.size(); i++) {
14187 final InstallParams childParams = new InstallParams(activeInstallSessions.get(i));
14188 childParams.mParentInstallParams = this;
14189 this.mChildParams.add(childParams);
14191 this.mCurrentState = new ArrayMap<>(mChildParams.size());
14195 void handleStartCopy() {
14196 for (InstallParams params : mChildParams) {
14197 params.handleStartCopy();
14198 if (params.mRet != INSTALL_SUCCEEDED) {
14199 mRet = params.mRet;
14205 void handleReturnCode() {
14206 for (InstallParams params : mChildParams) {
14207 params.handleReturnCode();
14208 if (params.mRet != INSTALL_SUCCEEDED) {
14209 mRet = params.mRet;
14214 void tryProcessInstallRequest(InstallArgs args, int currentStatus) {
14215 mCurrentState.put(args, currentStatus);
14216 if (mCurrentState.size() != mChildParams.size()) {
14219 int completeStatus = PackageManager.INSTALL_SUCCEEDED;
14220 for (Integer status : mCurrentState.values()) {
14221 if (status == PackageManager.INSTALL_UNKNOWN) {
14223 } else if (status != PackageManager.INSTALL_SUCCEEDED) {
14224 completeStatus = status;
14228 final List<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size());
14229 for (Map.Entry<InstallArgs, Integer> entry : mCurrentState.entrySet()) {
14230 installRequests.add(new InstallRequest(entry.getKey(),
14231 createPackageInstalledInfo(completeStatus)));
14233 processInstallRequestsAsync(
14234 completeStatus == PackageManager.INSTALL_SUCCEEDED,
14239 class InstallParams extends HandlerParams {
14240 // TODO: see if we can collapse this into ActiveInstallSession
14242 final OriginInfo origin;
14243 final MoveInfo move;
14244 final IPackageInstallObserver2 observer;
14246 @NonNull final InstallSource installSource;
14247 final String volumeUuid;
14248 private boolean mVerificationCompleted;
14249 private boolean mIntegrityVerificationCompleted;
14250 private boolean mEnableRollbackCompleted;
14251 private InstallArgs mArgs;
14253 final String packageAbiOverride;
14254 final String[] grantedRuntimePermissions;
14255 final List<String> whitelistedRestrictedPermissions;
14256 final VerificationInfo verificationInfo;
14257 final PackageParser.SigningDetails signingDetails;
14258 final int installReason;
14260 MultiPackageInstallParams mParentInstallParams;
14261 final long requiredInstalledVersionCode;
14262 final boolean forceQueryableOverride;
14263 final int mDataLoaderType;
14264 final int mSessionId;
14266 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14267 int installFlags, InstallSource installSource, String volumeUuid,
14268 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14269 String[] grantedPermissions, List<String> whitelistedRestrictedPermissions,
14270 SigningDetails signingDetails, int installReason,
14271 long requiredInstalledVersionCode, int dataLoaderType) {
14273 this.origin = origin;
14275 this.observer = observer;
14276 this.installFlags = installFlags;
14277 this.installSource = Preconditions.checkNotNull(installSource);
14278 this.volumeUuid = volumeUuid;
14279 this.verificationInfo = verificationInfo;
14280 this.packageAbiOverride = packageAbiOverride;
14281 this.grantedRuntimePermissions = grantedPermissions;
14282 this.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
14283 this.signingDetails = signingDetails;
14284 this.installReason = installReason;
14285 this.requiredInstalledVersionCode = requiredInstalledVersionCode;
14286 this.forceQueryableOverride = false;
14287 this.mDataLoaderType = dataLoaderType;
14288 this.mSessionId = -1;
14291 InstallParams(ActiveInstallSession activeInstallSession) {
14292 super(activeInstallSession.getUser());
14293 final PackageInstaller.SessionParams sessionParams =
14294 activeInstallSession.getSessionParams();
14295 if (DEBUG_INSTANT) {
14296 if ((sessionParams.installFlags
14297 & PackageManager.INSTALL_INSTANT_APP) != 0) {
14298 Slog.d(TAG, "Ephemeral install of " + activeInstallSession.getPackageName());
14301 verificationInfo = new VerificationInfo(
14302 sessionParams.originatingUri,
14303 sessionParams.referrerUri,
14304 sessionParams.originatingUid,
14305 activeInstallSession.getInstallerUid());
14306 origin = OriginInfo.fromStagedFile(activeInstallSession.getStagedDir());
14308 installReason = fixUpInstallReason(
14309 activeInstallSession.getInstallSource().installerPackageName,
14310 activeInstallSession.getInstallerUid(),
14311 sessionParams.installReason);
14312 observer = activeInstallSession.getObserver();
14313 installFlags = sessionParams.installFlags;
14314 installSource = activeInstallSession.getInstallSource();
14315 volumeUuid = sessionParams.volumeUuid;
14316 packageAbiOverride = sessionParams.abiOverride;
14317 grantedRuntimePermissions = sessionParams.grantedRuntimePermissions;
14318 whitelistedRestrictedPermissions = sessionParams.whitelistedRestrictedPermissions;
14319 signingDetails = activeInstallSession.getSigningDetails();
14320 requiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode;
14321 forceQueryableOverride = sessionParams.forceQueryableOverride;
14322 mDataLoaderType = (sessionParams.dataLoaderParams != null)
14323 ? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE;
14324 mSessionId = activeInstallSession.getSessionId();
14328 public String toString() {
14329 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14330 + " file=" + origin.file + "}";
14333 private int installLocationPolicy(PackageInfoLite pkgLite) {
14334 String packageName = pkgLite.packageName;
14335 int installLocation = pkgLite.installLocation;
14337 synchronized (mLock) {
14338 // Currently installed package which the new package is attempting to replace or
14339 // null if no such package is installed.
14340 AndroidPackage installedPkg = mPackages.get(packageName);
14341 // Package which currently owns the data which the new package will own if installed.
14342 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14343 // will be null whereas dataOwnerPkg will contain information about the package
14344 // which was uninstalled while keeping its data.
14345 AndroidPackage dataOwnerPkg = installedPkg;
14346 if (dataOwnerPkg == null) {
14347 PackageSetting ps = mSettings.mPackages.get(packageName);
14349 dataOwnerPkg = ps.pkg;
14353 if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST) {
14354 if (dataOwnerPkg == null) {
14355 Slog.w(TAG, "Required installed version code was "
14356 + requiredInstalledVersionCode
14357 + " but package is not installed");
14358 return PackageHelper.RECOMMEND_FAILED_WRONG_INSTALLED_VERSION;
14361 if (dataOwnerPkg.getLongVersionCode() != requiredInstalledVersionCode) {
14362 Slog.w(TAG, "Required installed version code was "
14363 + requiredInstalledVersionCode
14364 + " but actual installed version is "
14365 + dataOwnerPkg.getLongVersionCode());
14366 return PackageHelper.RECOMMEND_FAILED_WRONG_INSTALLED_VERSION;
14370 if (dataOwnerPkg != null) {
14371 if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags,
14372 dataOwnerPkg.isDebuggable())) {
14374 checkDowngrade(dataOwnerPkg, pkgLite);
14375 } catch (PackageManagerException e) {
14376 Slog.w(TAG, "Downgrade detected: " + e.getMessage());
14377 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
14382 if (installedPkg != null) {
14383 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
14384 // Check for updated system application.
14385 if (installedPkg.isSystem()) {
14386 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14388 // If current upgrade specifies particular preference
14389 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
14390 // Application explicitly specified internal.
14391 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14392 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
14393 // App explictly prefers external. Let policy decide
14395 // Prefer previous location
14396 if (installedPkg.isExternalStorage()) {
14397 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14399 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14403 // Invalid install. Return error code
14404 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
14408 return pkgLite.recommendedInstallLocation;
14412 * Invoke remote method to get package information and install
14413 * location values. Override install location based on default
14414 * policy if needed and then create install arguments based
14415 * on the install location.
14417 public void handleStartCopy() {
14418 int ret = PackageManager.INSTALL_SUCCEEDED;
14420 // If we're already staged, we've firmly committed to an install location
14421 if (origin.staged) {
14422 if (origin.file != null) {
14423 installFlags |= PackageManager.INSTALL_INTERNAL;
14425 throw new IllegalStateException("Invalid stage location");
14429 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
14430 final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14431 PackageInfoLite pkgLite = null;
14434 pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
14435 origin.resolvedPath, installFlags, packageAbiOverride);
14437 if (DEBUG_INSTANT && ephemeral) {
14438 Slog.v(TAG, "pkgLite for install: " + pkgLite);
14442 * If we have too little free space, try to free cache
14443 * before giving up.
14445 if (!origin.staged && pkgLite.recommendedInstallLocation
14446 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14447 // TODO: focus freeing disk space on the target device
14448 final StorageManager storage = StorageManager.from(mContext);
14449 final long lowThreshold = storage.getStorageLowBytes(
14450 Environment.getDataDirectory());
14452 final long sizeBytes = PackageManagerServiceUtils.calculateInstalledSize(
14453 origin.resolvedPath, packageAbiOverride);
14454 if (sizeBytes >= 0) {
14456 mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
14457 pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
14458 origin.resolvedPath, installFlags, packageAbiOverride);
14459 } catch (InstallerException e) {
14460 Slog.w(TAG, "Failed to free cache", e);
14465 * The cache free must have deleted the file we downloaded to install.
14467 * TODO: fix the "freeCache" call to not delete the file we care about.
14469 if (pkgLite.recommendedInstallLocation
14470 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14471 pkgLite.recommendedInstallLocation
14472 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
14477 if (ret == PackageManager.INSTALL_SUCCEEDED) {
14478 int loc = pkgLite.recommendedInstallLocation;
14479 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
14480 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14481 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
14482 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
14483 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14484 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
14485 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
14486 ret = PackageManager.INSTALL_FAILED_INVALID_APK;
14487 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14488 ret = PackageManager.INSTALL_FAILED_INVALID_URI;
14489 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
14490 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
14492 // Override with defaults if needed.
14493 loc = installLocationPolicy(pkgLite);
14494 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
14495 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
14496 } else if (loc == PackageHelper.RECOMMEND_FAILED_WRONG_INSTALLED_VERSION) {
14497 ret = PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION;
14498 } else if (!onInt) {
14499 // Override install location with flags
14500 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
14501 // Set the flag to install on external media.
14502 installFlags &= ~PackageManager.INSTALL_INTERNAL;
14503 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
14504 if (DEBUG_INSTANT) {
14505 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
14507 installFlags |= PackageManager.INSTALL_INSTANT_APP;
14508 installFlags &= ~PackageManager.INSTALL_INTERNAL;
14510 // Make sure the flag for installing on external
14512 installFlags |= PackageManager.INSTALL_INTERNAL;
14518 final InstallArgs args = createInstallArgs(this);
14519 mVerificationCompleted = true;
14520 mIntegrityVerificationCompleted = true;
14521 mEnableRollbackCompleted = true;
14524 if (ret == PackageManager.INSTALL_SUCCEEDED) {
14525 final int verificationId = mPendingVerificationToken++;
14527 // Perform package verification (unless we are simply moving the package).
14528 if (!origin.existing) {
14529 PackageVerificationState verificationState =
14530 new PackageVerificationState(this);
14531 mPendingVerification.append(verificationId, verificationState);
14533 sendIntegrityVerificationRequest(verificationId, pkgLite, verificationState);
14534 ret = sendPackageVerificationRequest(
14535 verificationId, pkgLite, verificationState);
14537 // If both verifications are skipped, we should remove the state.
14538 if (verificationState.areAllVerificationsComplete()) {
14539 mPendingVerification.remove(verificationId);
14544 if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
14545 // TODO(ruhler) b/112431924: Don't do this in case of 'move'?
14546 final int enableRollbackToken = mPendingEnableRollbackToken++;
14547 Trace.asyncTraceBegin(
14548 TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
14549 mPendingEnableRollback.append(enableRollbackToken, this);
14551 Intent enableRollbackIntent = new Intent(Intent.ACTION_PACKAGE_ENABLE_ROLLBACK);
14552 enableRollbackIntent.putExtra(
14553 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN,
14554 enableRollbackToken);
14555 enableRollbackIntent.putExtra(
14556 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_SESSION_ID,
14558 enableRollbackIntent.setType(PACKAGE_MIME_TYPE);
14559 enableRollbackIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14561 // Allow the broadcast to be sent before boot complete.
14562 // This is needed when committing the apk part of a staged
14563 // session in early boot. The rollback manager registers
14564 // its receiver early enough during the boot process that
14565 // it will not miss the broadcast.
14566 enableRollbackIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
14568 mContext.sendOrderedBroadcastAsUser(enableRollbackIntent, UserHandle.SYSTEM,
14569 android.Manifest.permission.PACKAGE_ROLLBACK_AGENT,
14570 new BroadcastReceiver() {
14572 public void onReceive(Context context, Intent intent) {
14573 // the duration to wait for rollback to be enabled, in millis
14574 long rollbackTimeout = DeviceConfig.getLong(
14575 DeviceConfig.NAMESPACE_ROLLBACK,
14576 PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS,
14577 DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS);
14578 if (rollbackTimeout < 0) {
14579 rollbackTimeout = DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS;
14581 final Message msg = mHandler.obtainMessage(
14582 ENABLE_ROLLBACK_TIMEOUT);
14583 msg.arg1 = enableRollbackToken;
14584 msg.arg2 = mSessionId;
14585 mHandler.sendMessageDelayed(msg, rollbackTimeout);
14587 }, null, 0, null, null);
14589 mEnableRollbackCompleted = false;
14597 * Send a request to check the integrity of the package.
14599 void sendIntegrityVerificationRequest(
14600 int verificationId,
14601 PackageInfoLite pkgLite,
14602 PackageVerificationState verificationState) {
14603 if (!isIntegrityVerificationEnabled()) {
14604 // Consider the integrity check as passed.
14605 verificationState.setIntegrityVerificationResult(
14606 PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
14610 final Intent integrityVerification =
14611 new Intent(Intent.ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
14613 integrityVerification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14614 PACKAGE_MIME_TYPE);
14616 final int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
14617 | Intent.FLAG_RECEIVER_REGISTERED_ONLY
14618 | Intent.FLAG_RECEIVER_FOREGROUND;
14619 integrityVerification.addFlags(flags);
14621 integrityVerification.putExtra(EXTRA_VERIFICATION_ID, verificationId);
14622 integrityVerification.putExtra(EXTRA_PACKAGE_NAME, pkgLite.packageName);
14623 integrityVerification.putExtra(EXTRA_VERSION_CODE, pkgLite.versionCode);
14624 integrityVerification.putExtra(EXTRA_LONG_VERSION_CODE, pkgLite.getLongVersionCode());
14625 populateInstallerExtras(integrityVerification);
14627 // send to integrity component only.
14628 integrityVerification.setPackage("android");
14630 DeviceIdleInternal idleController =
14631 mInjector.getLocalDeviceIdleController();
14632 final long idleDuration = getVerificationTimeout();
14634 idleController.addPowerSaveTempWhitelistAppDirect(Process.myUid(),
14636 false, "integrity component");
14637 mContext.sendOrderedBroadcastAsUser(integrityVerification, UserHandle.SYSTEM,
14638 /* receiverPermission= */ null,
14639 new BroadcastReceiver() {
14641 public void onReceive(Context context, Intent intent) {
14642 final Message msg =
14643 mHandler.obtainMessage(CHECK_PENDING_INTEGRITY_VERIFICATION);
14644 msg.arg1 = verificationId;
14645 // TODO: do we want to use the same timeout?
14646 mHandler.sendMessageDelayed(msg, getVerificationTimeout());
14648 }, /* scheduler= */ null,
14649 /* initialCode= */ 0,
14650 /* initialData= */ null,
14651 /* initialExtras= */ null);
14653 Trace.asyncTraceBegin(
14654 TRACE_TAG_PACKAGE_MANAGER, "integrity_verification", verificationId);
14656 // stop the copy until verification succeeds.
14657 mIntegrityVerificationCompleted = false;
14661 * Send a request to verifier(s) to verify the package if necessary, and return
14662 * {@link PackageManager#INSTALL_SUCCEEDED} if succeeded.
14664 int sendPackageVerificationRequest(
14665 int verificationId,
14666 PackageInfoLite pkgLite,
14667 PackageVerificationState verificationState) {
14668 int ret = INSTALL_SUCCEEDED;
14670 // TODO: http://b/22976637
14671 // Apps installed for "all" users use the device owner to verify the app
14672 UserHandle verifierUser = getUser();
14673 if (verifierUser == UserHandle.ALL) {
14674 verifierUser = UserHandle.SYSTEM;
14678 * Determine if we have any installed package verifiers. If we
14679 * do, then we'll defer to them to verify the packages.
14681 final int requiredUid = mRequiredVerifierPackage == null ? -1
14682 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
14683 verifierUser.getIdentifier());
14684 verificationState.setRequiredVerifierUid(requiredUid);
14685 final int installerUid =
14686 verificationInfo == null ? -1 : verificationInfo.installerUid;
14687 if (!origin.existing && requiredUid != -1
14688 && isVerificationEnabled(
14689 pkgLite, verifierUser.getIdentifier(), installFlags, installerUid)) {
14690 final Intent verification = new Intent(
14691 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
14692 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14693 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14694 PACKAGE_MIME_TYPE);
14695 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14697 // Query all live verifiers based on current user state
14698 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
14699 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
14700 false /*allowDynamicSplits*/);
14702 if (DEBUG_VERIFY) {
14703 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
14704 + verification.toString() + " with " + pkgLite.verifiers.length
14705 + " optional verifiers");
14708 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14710 verification.putExtra(
14711 PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, installFlags);
14713 verification.putExtra(
14714 PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, pkgLite.packageName);
14716 verification.putExtra(
14717 PackageManager.EXTRA_VERIFICATION_VERSION_CODE, pkgLite.versionCode);
14719 verification.putExtra(
14720 PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
14721 pkgLite.getLongVersionCode());
14723 populateInstallerExtras(verification);
14725 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
14726 receivers, verificationState);
14728 DeviceIdleInternal idleController =
14729 mInjector.getLocalDeviceIdleController();
14730 final long idleDuration = getVerificationTimeout();
14733 * If any sufficient verifiers were listed in the package
14734 * manifest, attempt to ask them.
14736 if (sufficientVerifiers != null) {
14737 final int n = sufficientVerifiers.size();
14739 Slog.i(TAG, "Additional verifiers required, but none installed.");
14740 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
14742 for (int i = 0; i < n; i++) {
14743 final ComponentName verifierComponent = sufficientVerifiers.get(i);
14744 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14745 verifierComponent.getPackageName(), idleDuration,
14746 verifierUser.getIdentifier(), false, "package verifier");
14748 final Intent sufficientIntent = new Intent(verification);
14749 sufficientIntent.setComponent(verifierComponent);
14750 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
14755 final ComponentName requiredVerifierComponent = matchComponentForVerifier(
14756 mRequiredVerifierPackage, receivers);
14757 if (mRequiredVerifierPackage != null) {
14759 * Send the intent to the required verification agent,
14760 * but only start the verification timeout after the
14761 * target BroadcastReceivers have run.
14763 verification.setComponent(requiredVerifierComponent);
14764 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14765 mRequiredVerifierPackage, idleDuration,
14766 verifierUser.getIdentifier(), false, "package verifier");
14767 mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
14768 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14769 new BroadcastReceiver() {
14771 public void onReceive(Context context, Intent intent) {
14772 final Message msg = mHandler
14773 .obtainMessage(CHECK_PENDING_VERIFICATION);
14774 msg.arg1 = verificationId;
14775 mHandler.sendMessageDelayed(msg, getVerificationTimeout());
14777 }, null, 0, null, null);
14779 Trace.asyncTraceBegin(
14780 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
14783 * We don't want the copy to proceed until verification
14786 mVerificationCompleted = false;
14789 verificationState.setVerifierResponse(
14790 requiredUid, PackageManager.VERIFICATION_ALLOW);
14795 void populateInstallerExtras(Intent intent) {
14796 intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
14797 installSource.initiatingPackageName);
14799 if (verificationInfo != null) {
14800 if (verificationInfo.originatingUri != null) {
14801 intent.putExtra(Intent.EXTRA_ORIGINATING_URI,
14802 verificationInfo.originatingUri);
14804 if (verificationInfo.referrer != null) {
14805 intent.putExtra(Intent.EXTRA_REFERRER,
14806 verificationInfo.referrer);
14808 if (verificationInfo.originatingUid >= 0) {
14809 intent.putExtra(Intent.EXTRA_ORIGINATING_UID,
14810 verificationInfo.originatingUid);
14812 if (verificationInfo.installerUid >= 0) {
14813 intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
14814 verificationInfo.installerUid);
14819 void setReturnCode(int ret) {
14820 if (mRet == PackageManager.INSTALL_SUCCEEDED) {
14821 // Only update mRet if it was previously INSTALL_SUCCEEDED to
14822 // ensure we do not overwrite any previous failure results.
14827 void handleVerificationFinished() {
14828 if (!mVerificationCompleted) {
14829 mVerificationCompleted = true;
14830 if (mIntegrityVerificationCompleted) {
14831 handleReturnCode();
14833 // integrity verification still pending.
14837 void handleIntegrityVerificationFinished() {
14838 if (!mIntegrityVerificationCompleted) {
14839 mIntegrityVerificationCompleted = true;
14840 if (mVerificationCompleted) {
14841 handleReturnCode();
14843 // verifier still pending
14848 void handleRollbackEnabled() {
14849 // TODO(ruhler) b/112431924: Consider halting the install if we
14850 // couldn't enable rollback.
14851 mEnableRollbackCompleted = true;
14852 handleReturnCode();
14856 void handleReturnCode() {
14857 if (mVerificationCompleted
14858 && mIntegrityVerificationCompleted && mEnableRollbackCompleted) {
14859 if ((installFlags & PackageManager.INSTALL_DRY_RUN) != 0) {
14860 String packageName = "";
14862 PackageLite packageInfo =
14863 new PackageParser().parsePackageLite(origin.file, 0);
14864 packageName = packageInfo.packageName;
14865 } catch (PackageParserException e) {
14866 Slog.e(TAG, "Can't parse package at " + origin.file.getAbsolutePath(), e);
14869 observer.onPackageInstalled(packageName, mRet, "Dry run", new Bundle());
14870 } catch (RemoteException e) {
14871 Slog.i(TAG, "Observer no longer exists.");
14875 if (mRet == PackageManager.INSTALL_SUCCEEDED) {
14876 mRet = mArgs.copyApk();
14878 processPendingInstall(mArgs, mRet);
14883 private InstallArgs createInstallArgs(InstallParams params) {
14884 if (params.move != null) {
14885 return new MoveInstallArgs(params);
14887 return new FileInstallArgs(params);
14892 * Create args that describe an existing installed package. Typically used
14893 * when cleaning up old installs, or used as a move source.
14895 private InstallArgs createInstallArgsForExisting(String codePath,
14896 String resourcePath, String[] instructionSets) {
14897 return new FileInstallArgs(codePath, resourcePath, instructionSets);
14900 static abstract class InstallArgs {
14901 /** @see InstallParams#origin */
14902 final OriginInfo origin;
14903 /** @see InstallParams#move */
14904 final MoveInfo move;
14906 final IPackageInstallObserver2 observer;
14907 // Always refers to PackageManager flags only
14908 final int installFlags;
14909 @NonNull final InstallSource installSource;
14910 final String volumeUuid;
14911 final UserHandle user;
14912 final String abiOverride;
14913 final String[] installGrantPermissions;
14914 final List<String> whitelistedRestrictedPermissions;
14915 /** If non-null, drop an async trace when the install completes */
14916 final String traceMethod;
14917 final int traceCookie;
14918 final PackageParser.SigningDetails signingDetails;
14919 final int installReason;
14920 final boolean forceQueryableOverride;
14921 @Nullable final MultiPackageInstallParams mMultiPackageInstallParams;
14922 final int mDataLoaderType;
14924 // The list of instruction sets supported by this app. This is currently
14925 // only used during the rmdex() phase to clean up resources. We can get rid of this
14926 // if we move dex files under the common app path.
14927 /* nullable */ String[] instructionSets;
14929 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14930 int installFlags, InstallSource installSource, String volumeUuid,
14931 UserHandle user, String[] instructionSets,
14932 String abiOverride, String[] installGrantPermissions,
14933 List<String> whitelistedRestrictedPermissions,
14934 String traceMethod, int traceCookie, SigningDetails signingDetails,
14935 int installReason, boolean forceQueryableOverride,
14936 MultiPackageInstallParams multiPackageInstallParams, int dataLoaderType) {
14937 this.origin = origin;
14939 this.installFlags = installFlags;
14940 this.observer = observer;
14941 this.installSource = Preconditions.checkNotNull(installSource);
14942 this.volumeUuid = volumeUuid;
14944 this.instructionSets = instructionSets;
14945 this.abiOverride = abiOverride;
14946 this.installGrantPermissions = installGrantPermissions;
14947 this.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
14948 this.traceMethod = traceMethod;
14949 this.traceCookie = traceCookie;
14950 this.signingDetails = signingDetails;
14951 this.installReason = installReason;
14952 this.forceQueryableOverride = forceQueryableOverride;
14953 this.mMultiPackageInstallParams = multiPackageInstallParams;
14954 this.mDataLoaderType = dataLoaderType;
14958 InstallArgs(InstallParams params) {
14959 this(params.origin, params.move, params.observer, params.installFlags,
14960 params.installSource, params.volumeUuid,
14961 params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
14962 params.grantedRuntimePermissions, params.whitelistedRestrictedPermissions,
14963 params.traceMethod, params.traceCookie, params.signingDetails,
14964 params.installReason, params.forceQueryableOverride,
14965 params.mParentInstallParams, params.mDataLoaderType);
14968 abstract int copyApk();
14969 abstract int doPreInstall(int status);
14972 * Rename package into final resting place. All paths on the given
14973 * scanned package should be updated to reflect the rename.
14975 abstract boolean doRename(int status, ParsedPackage parsedPackage);
14976 abstract int doPostInstall(int status, int uid);
14978 /** @see PackageSettingBase#codePathString */
14979 abstract String getCodePath();
14980 /** @see PackageSettingBase#resourcePathString */
14981 abstract String getResourcePath();
14983 // Need installer lock especially for dex file removal.
14984 abstract void cleanUpResourcesLI();
14985 abstract boolean doPostDeleteLI(boolean delete);
14988 * Called before the source arguments are copied. This is used mostly
14989 * for MoveParams when it needs to read the source file to put it in the
14993 return PackageManager.INSTALL_SUCCEEDED;
14997 * Called after the source arguments are copied. This is used mostly for
14998 * MoveParams when it needs to read the source file to put it in the
15001 int doPostCopy(int uid) {
15002 return PackageManager.INSTALL_SUCCEEDED;
15005 protected boolean isEphemeral() {
15006 return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15009 UserHandle getUser() {
15014 void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15015 if (!allCodePaths.isEmpty()) {
15016 if (instructionSets == null) {
15017 throw new IllegalStateException("instructionSet == null");
15019 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15020 for (String codePath : allCodePaths) {
15021 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15023 mInstaller.rmdex(codePath, dexCodeInstructionSet);
15024 } catch (InstallerException ignored) {
15032 * Logic to handle installation of new applications, including copying
15033 * and renaming logic.
15035 class FileInstallArgs extends InstallArgs {
15036 private File codeFile;
15037 private File resourceFile;
15039 // Example topology:
15040 // /data/app/com.example/base.apk
15041 // /data/app/com.example/split_foo.apk
15042 // /data/app/com.example/lib/arm/libfoo.so
15043 // /data/app/com.example/lib/arm64/libfoo.so
15044 // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15047 FileInstallArgs(InstallParams params) {
15051 /** Existing install */
15052 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15053 super(OriginInfo.fromNothing(), null, null, 0, InstallSource.EMPTY,
15054 null, null, instructionSets, null, null, null, null, 0,
15055 PackageParser.SigningDetails.UNKNOWN,
15056 PackageManager.INSTALL_REASON_UNKNOWN, false, null /* parent */,
15057 DataLoaderType.NONE);
15058 this.codeFile = (codePath != null) ? new File(codePath) : null;
15059 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15063 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15065 return doCopyApk();
15067 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15071 private int doCopyApk() {
15072 if (origin.staged) {
15073 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15074 codeFile = origin.file;
15075 resourceFile = origin.file;
15076 return PackageManager.INSTALL_SUCCEEDED;
15080 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15081 final File tempDir =
15082 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15083 codeFile = tempDir;
15084 resourceFile = tempDir;
15085 } catch (IOException e) {
15086 Slog.w(TAG, "Failed to create copy file: " + e);
15087 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15090 int ret = PackageManagerServiceUtils.copyPackage(
15091 origin.file.getAbsolutePath(), codeFile);
15092 if (ret != PackageManager.INSTALL_SUCCEEDED) {
15093 Slog.e(TAG, "Failed to copy package");
15097 final boolean isIncremental = isIncrementalPath(codeFile.getAbsolutePath());
15098 final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15099 NativeLibraryHelper.Handle handle = null;
15101 handle = NativeLibraryHelper.Handle.create(codeFile);
15102 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15103 abiOverride, isIncremental);
15104 } catch (IOException e) {
15105 Slog.e(TAG, "Copying native libraries failed", e);
15106 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15108 IoUtils.closeQuietly(handle);
15114 int doPreInstall(int status) {
15115 if (status != PackageManager.INSTALL_SUCCEEDED) {
15122 boolean doRename(int status, ParsedPackage parsedPackage) {
15123 if (status != PackageManager.INSTALL_SUCCEEDED) {
15128 final File targetDir = codeFile.getParentFile();
15129 final File beforeCodeFile = codeFile;
15130 final File afterCodeFile = getNextCodePath(targetDir, parsedPackage.getPackageName());
15132 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15133 final boolean onIncremental = mIncrementalManager != null
15134 && isIncrementalPath(beforeCodeFile.getAbsolutePath());
15136 makeDirRecursive(afterCodeFile.getParentFile(), 0775);
15137 if (onIncremental) {
15138 mIncrementalManager.renameCodePath(beforeCodeFile, afterCodeFile);
15140 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15142 } catch (IOException | ErrnoException e) {
15143 Slog.w(TAG, "Failed to rename", e);
15147 //TODO(b/136132412): enable selinux restorecon for incremental directories
15148 if (!onIncremental && !SELinux.restoreconRecursive(afterCodeFile)) {
15149 Slog.w(TAG, "Failed to restorecon");
15153 // Reflect the rename internally
15154 codeFile = afterCodeFile;
15155 resourceFile = afterCodeFile;
15157 // Reflect the rename in scanned details
15159 parsedPackage.setCodePath(afterCodeFile.getCanonicalPath());
15160 } catch (IOException e) {
15161 Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
15164 parsedPackage.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15165 afterCodeFile, parsedPackage.getBaseCodePath()));
15166 parsedPackage.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15167 afterCodeFile, parsedPackage.getSplitCodePaths()));
15172 int doPostInstall(int status, int uid) {
15173 if (status != PackageManager.INSTALL_SUCCEEDED) {
15180 String getCodePath() {
15181 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15185 String getResourcePath() {
15186 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15189 private boolean cleanUp() {
15190 if (codeFile == null || !codeFile.exists()) {
15194 String codePath = codeFile.getAbsolutePath();
15195 if (mIncrementalManager != null && isIncrementalPath(codePath)) {
15196 mIncrementalManager.closeStorage(codePath);
15199 removeCodePathLI(codeFile);
15201 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15202 resourceFile.delete();
15208 void cleanUpResourcesLI() {
15209 // Try enumerating all code paths before deleting
15210 List<String> allCodePaths = Collections.EMPTY_LIST;
15211 if (codeFile != null && codeFile.exists()) {
15213 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15214 allCodePaths = pkg.getAllCodePaths();
15215 } catch (PackageParserException e) {
15216 // Ignored; we tried our best
15221 removeDexFiles(allCodePaths, instructionSets);
15224 boolean doPostDeleteLI(boolean delete) {
15225 // XXX err, shouldn't we respect the delete flag?
15226 cleanUpResourcesLI();
15232 * Logic to handle movement of existing installed applications.
15234 class MoveInstallArgs extends InstallArgs {
15235 private File codeFile;
15236 private File resourceFile;
15239 MoveInstallArgs(InstallParams params) {
15244 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15245 + move.fromUuid + " to " + move.toUuid);
15246 synchronized (mInstaller) {
15248 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15249 move.appId, move.seinfo, move.targetSdkVersion,
15250 move.fromCodePath);
15251 } catch (InstallerException e) {
15252 Slog.w(TAG, "Failed to move app", e);
15253 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15257 final String toPathName = new File(move.fromCodePath).getName();
15258 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), toPathName);
15259 resourceFile = codeFile;
15260 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15262 return PackageManager.INSTALL_SUCCEEDED;
15265 int doPreInstall(int status) {
15266 if (status != PackageManager.INSTALL_SUCCEEDED) {
15267 cleanUp(move.toUuid);
15273 boolean doRename(int status, ParsedPackage parsedPackage) {
15274 if (status != PackageManager.INSTALL_SUCCEEDED) {
15275 cleanUp(move.toUuid);
15282 int doPostInstall(int status, int uid) {
15283 if (status == PackageManager.INSTALL_SUCCEEDED) {
15284 cleanUp(move.fromUuid);
15286 cleanUp(move.toUuid);
15292 String getCodePath() {
15293 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15297 String getResourcePath() {
15298 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15301 private boolean cleanUp(String volumeUuid) {
15302 final String toPathName = new File(move.fromCodePath).getName();
15303 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15305 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15306 final int[] userIds = mUserManager.getUserIds();
15307 synchronized (mInstallLock) {
15308 // Clean up both app data and code
15309 // All package moves are frozen until finished
15311 // We purposefully exclude FLAG_STORAGE_EXTERNAL here, since
15312 // this task was only focused on moving data on internal storage.
15313 // We don't want ART profiles cleared, because they don't move,
15314 // so we would be deleting the only copy (b/149200535).
15315 final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE
15316 | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES;
15317 for (int userId : userIds) {
15319 mInstaller.destroyAppData(volumeUuid, move.packageName, userId, flags, 0);
15320 } catch (InstallerException e) {
15321 Slog.w(TAG, String.valueOf(e));
15324 removeCodePathLI(codeFile);
15329 void cleanUpResourcesLI() {
15330 throw new UnsupportedOperationException();
15333 boolean doPostDeleteLI(boolean delete) {
15334 throw new UnsupportedOperationException();
15339 * Given {@code targetDir}, returns {@code targetDir/~~[randomStrA]/[packageName]-[randomStrB].}
15340 * Makes sure that {@code targetDir/~~[randomStrA]} directory doesn't exist.
15341 * Notice that this method doesn't actually create any directory.
15343 * @param targetDir Directory that is two-levels up from the result directory.
15344 * @param packageName Name of the package whose code files are to be installed under the result
15346 * @return File object for the directory that should hold the code files of {@code packageName}.
15348 private File getNextCodePath(File targetDir, String packageName) {
15349 SecureRandom random = new SecureRandom();
15350 byte[] bytes = new byte[16];
15351 File firstLevelDir;
15353 random.nextBytes(bytes);
15354 String dirName = RANDOM_DIR_PREFIX
15355 + Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15356 firstLevelDir = new File(targetDir, dirName);
15357 } while (firstLevelDir.exists());
15358 random.nextBytes(bytes);
15359 String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15360 return new File(firstLevelDir, packageName + "-" + suffix);
15363 static class PackageInstalledInfo {
15366 // The set of users that originally had this package installed.
15368 // The set of users that now have this package installed.
15370 AndroidPackage pkg;
15373 String installerPackageName;
15374 PackageRemovedInfo removedInfo;
15375 ArrayMap<String, PackageInstalledInfo> addedChildPackages;
15376 // The set of packages consuming this shared library or null if no consumers exist.
15377 ArrayList<AndroidPackage> libraryConsumers;
15378 PackageFreezer freezer;
15380 public void setError(int code, String msg) {
15381 setReturnCode(code);
15382 setReturnMessage(msg);
15386 public void setError(String msg, PackageParserException e) {
15387 setReturnCode(e.error);
15388 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15389 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15390 for (int i = 0; i < childCount; i++) {
15391 addedChildPackages.valueAt(i).setError(msg, e);
15393 Slog.w(TAG, msg, e);
15396 public void setError(String msg, PackageManagerException e) {
15397 returnCode = e.error;
15398 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15399 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15400 for (int i = 0; i < childCount; i++) {
15401 addedChildPackages.valueAt(i).setError(msg, e);
15403 Slog.w(TAG, msg, e);
15406 public void setReturnCode(int returnCode) {
15407 this.returnCode = returnCode;
15408 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15409 for (int i = 0; i < childCount; i++) {
15410 addedChildPackages.valueAt(i).returnCode = returnCode;
15414 private void setReturnMessage(String returnMsg) {
15415 this.returnMsg = returnMsg;
15416 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15417 for (int i = 0; i < childCount; i++) {
15418 addedChildPackages.valueAt(i).returnMsg = returnMsg;
15422 // In some error cases we want to convey more info back to the observer
15423 String origPackage;
15424 String origPermission;
15427 private static void updateDigest(MessageDigest digest, File file) throws IOException {
15428 try (DigestInputStream digestStream =
15429 new DigestInputStream(new FileInputStream(file), digest)) {
15430 while (digestStream.read() != -1) {} // nothing to do; just plow through the file
15434 private void removeNativeBinariesLI(PackageSetting ps) {
15436 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
15440 @GuardedBy("mLock")
15441 private void enableSystemPackageLPw(AndroidPackage pkg) {
15442 mSettings.enableSystemPackageLPw(pkg.getPackageName());
15445 @GuardedBy("mLock")
15446 private boolean disableSystemPackageLPw(AndroidPackage oldPkg) {
15447 return mSettings.disableSystemPackageLPw(oldPkg.getPackageName(), true);
15450 private void updateSettingsLI(AndroidPackage newPackage, InstallArgs installArgs,
15451 int[] allUsers, PackageInstalledInfo res) {
15452 updateSettingsInternalLI(newPackage, installArgs, allUsers, res);
15455 private void updateSettingsInternalLI(AndroidPackage pkg, InstallArgs installArgs,
15456 int[] allUsers, PackageInstalledInfo res) {
15457 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
15459 final String pkgName = pkg.getPackageName();
15460 final int[] installedForUsers = res.origUsers;
15461 final int installReason = installArgs.installReason;
15462 InstallSource installSource = installArgs.installSource;
15463 final String installerPackageName = installSource.installerPackageName;
15465 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.getCodePath());
15466 synchronized (mLock) {
15467 // NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
15468 mPermissionManager.updatePermissions(pkgName, pkg);
15469 // For system-bundled packages, we assume that installing an upgraded version
15470 // of the package implies that the user actually wants to run that new code,
15471 // so we enable the package.
15472 final PackageSetting ps = mSettings.mPackages.get(pkgName);
15473 final int userId = installArgs.user.getIdentifier();
15475 if (pkg.isSystem()) {
15476 if (DEBUG_INSTALL) {
15477 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
15479 // Enable system package for requested users
15480 if (res.origUsers != null) {
15481 for (int origUserId : res.origUsers) {
15482 if (userId == UserHandle.USER_ALL || userId == origUserId) {
15483 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
15484 origUserId, installerPackageName);
15488 // Also convey the prior install/uninstall state
15489 if (allUsers != null && installedForUsers != null) {
15490 for (int currentUserId : allUsers) {
15491 final boolean installed = ArrayUtils.contains(
15492 installedForUsers, currentUserId);
15493 if (DEBUG_INSTALL) {
15494 Slog.d(TAG, " user " + currentUserId + " => " + installed);
15496 ps.setInstalled(installed, currentUserId);
15498 // these install state changes will be persisted in the
15499 // upcoming call to mSettings.writeLPr().
15503 // Retrieve the overlays for shared libraries of the package.
15504 if (!ps.getPkgState().getUsesLibraryInfos().isEmpty()) {
15505 for (SharedLibraryInfo sharedLib : ps.getPkgState().getUsesLibraryInfos()) {
15506 for (int currentUserId : UserManagerService.getInstance().getUserIds()) {
15507 if (!sharedLib.isDynamic()) {
15508 // TODO(146804378): Support overlaying static shared libraries
15511 final PackageSetting libPs = mSettings.mPackages.get(
15512 sharedLib.getPackageName());
15513 if (libPs == null) {
15516 final String[] overlayPaths = libPs.getOverlayPaths(currentUserId);
15517 if (overlayPaths != null) {
15518 ps.setOverlayPathsForLibrary(sharedLib.getName(),
15519 Arrays.asList(overlayPaths), currentUserId);
15525 // It's implied that when a user requests installation, they want the app to be
15526 // installed and enabled.
15527 if (userId != UserHandle.USER_ALL) {
15528 ps.setInstalled(true, userId);
15529 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
15532 if (installSource.initiatingPackageName != null) {
15533 final PackageSetting ips = mSettings.mPackages.get(
15534 installSource.initiatingPackageName);
15536 installSource = installSource.setInitiatingPackageSignatures(
15540 ps.setInstallSource(installSource);
15541 mSettings.addInstallerPackageNames(installSource);
15543 // When replacing an existing package, preserve the original install reason for all
15544 // users that had the package installed before.
15545 final Set<Integer> previousUserIds = new ArraySet<>();
15546 if (res.removedInfo != null && res.removedInfo.installReasons != null) {
15547 final int installReasonCount = res.removedInfo.installReasons.size();
15548 for (int i = 0; i < installReasonCount; i++) {
15549 final int previousUserId = res.removedInfo.installReasons.keyAt(i);
15550 final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
15551 ps.setInstallReason(previousInstallReason, previousUserId);
15552 previousUserIds.add(previousUserId);
15556 // Set install reason for users that are having the package newly installed.
15557 if (userId == UserHandle.USER_ALL) {
15558 for (int currentUserId : mUserManager.getUserIds()) {
15559 if (!previousUserIds.contains(currentUserId)) {
15560 ps.setInstallReason(installReason, currentUserId);
15563 } else if (!previousUserIds.contains(userId)) {
15564 ps.setInstallReason(installReason, userId);
15566 mSettings.writeKernelMappingLPr(ps);
15568 res.name = pkgName;
15569 res.uid = pkg.getUid();
15571 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
15572 //to update install status
15573 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
15574 mSettings.writeLPr();
15575 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15578 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15581 private static class InstallRequest {
15582 public final InstallArgs args;
15583 public final PackageInstalledInfo installResult;
15585 private InstallRequest(InstallArgs args, PackageInstalledInfo res) {
15587 this.installResult = res;
15591 @GuardedBy({"mInstallLock", "mLock"})
15592 private void installPackagesTracedLI(List<InstallRequest> requests) {
15594 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages");
15595 installPackagesLI(requests);
15597 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15602 * Package state to commit to memory and disk after reconciliation has completed.
15604 private static class CommitRequest {
15605 final Map<String, ReconciledPackage> reconciledPackages;
15606 final int[] mAllUsers;
15608 private CommitRequest(Map<String, ReconciledPackage> reconciledPackages, int[] allUsers) {
15609 this.reconciledPackages = reconciledPackages;
15610 this.mAllUsers = allUsers;
15615 * Package scan results and related request details used to reconcile the potential addition of
15616 * one or more packages to the system.
15618 * Reconcile will take a set of package details that need to be committed to the system and make
15619 * sure that they are valid in the context of the system and the other installing apps. Any
15620 * invalid state or app will result in a failed reconciliation and thus whatever operation (such
15621 * as install) led to the request.
15623 private static class ReconcileRequest {
15624 public final Map<String, ScanResult> scannedPackages;
15626 public final Map<String, AndroidPackage> allPackages;
15627 public final Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource;
15628 public final Map<String, InstallArgs> installArgs;
15629 public final Map<String, PackageInstalledInfo> installResults;
15630 public final Map<String, PrepareResult> preparedPackages;
15631 public final Map<String, VersionInfo> versionInfos;
15632 public final Map<String, PackageSetting> lastStaticSharedLibSettings;
15634 private ReconcileRequest(Map<String, ScanResult> scannedPackages,
15635 Map<String, InstallArgs> installArgs,
15636 Map<String, PackageInstalledInfo> installResults,
15637 Map<String, PrepareResult> preparedPackages,
15638 Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource,
15639 Map<String, AndroidPackage> allPackages,
15640 Map<String, VersionInfo> versionInfos,
15641 Map<String, PackageSetting> lastStaticSharedLibSettings) {
15642 this.scannedPackages = scannedPackages;
15643 this.installArgs = installArgs;
15644 this.installResults = installResults;
15645 this.preparedPackages = preparedPackages;
15646 this.sharedLibrarySource = sharedLibrarySource;
15647 this.allPackages = allPackages;
15648 this.versionInfos = versionInfos;
15649 this.lastStaticSharedLibSettings = lastStaticSharedLibSettings;
15652 private ReconcileRequest(Map<String, ScanResult> scannedPackages,
15653 Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource,
15654 Map<String, AndroidPackage> allPackages,
15655 Map<String, VersionInfo> versionInfos,
15656 Map<String, PackageSetting> lastStaticSharedLibSettings) {
15657 this(scannedPackages, Collections.emptyMap(), Collections.emptyMap(),
15658 Collections.emptyMap(), sharedLibrarySource, allPackages, versionInfos,
15659 lastStaticSharedLibSettings);
15662 private static class ReconcileFailure extends PackageManagerException {
15663 ReconcileFailure(String message) {
15664 super("Reconcile failed: " + message);
15666 ReconcileFailure(int reason, String message) {
15667 super(reason, "Reconcile failed: " + message);
15669 ReconcileFailure(PackageManagerException e) {
15670 this(e.error, e.getMessage());
15675 * A container of all data needed to commit a package to in-memory data structures and to disk.
15676 * TODO: move most of the data contained her into a PackageSetting for commit.
15678 private static class ReconciledPackage {
15679 public final ReconcileRequest request;
15680 public final PackageSetting pkgSetting;
15681 public final ScanResult scanResult;
15682 // TODO: Remove install-specific details from the reconcile result
15683 public final PackageInstalledInfo installResult;
15684 @Nullable public final PrepareResult prepareResult;
15685 @Nullable public final InstallArgs installArgs;
15686 public final DeletePackageAction deletePackageAction;
15687 public final List<SharedLibraryInfo> allowedSharedLibraryInfos;
15688 public final SigningDetails signingDetails;
15689 public final boolean sharedUserSignaturesChanged;
15690 public ArrayList<SharedLibraryInfo> collectedSharedLibraryInfos;
15691 public final boolean removeAppKeySetData;
15693 private ReconciledPackage(ReconcileRequest request,
15694 InstallArgs installArgs,
15695 PackageSetting pkgSetting,
15696 PackageInstalledInfo installResult,
15697 PrepareResult prepareResult,
15698 ScanResult scanResult,
15699 DeletePackageAction deletePackageAction,
15700 List<SharedLibraryInfo> allowedSharedLibraryInfos,
15701 SigningDetails signingDetails,
15702 boolean sharedUserSignaturesChanged,
15703 boolean removeAppKeySetData) {
15704 this.request = request;
15705 this.installArgs = installArgs;
15706 this.pkgSetting = pkgSetting;
15707 this.installResult = installResult;
15708 this.prepareResult = prepareResult;
15709 this.scanResult = scanResult;
15710 this.deletePackageAction = deletePackageAction;
15711 this.allowedSharedLibraryInfos = allowedSharedLibraryInfos;
15712 this.signingDetails = signingDetails;
15713 this.sharedUserSignaturesChanged = sharedUserSignaturesChanged;
15714 this.removeAppKeySetData = removeAppKeySetData;
15718 * Returns a combined set of packages containing the packages already installed combined
15719 * with the package(s) currently being installed. The to-be installed packages take
15720 * precedence and may shadow already installed packages.
15722 private Map<String, AndroidPackage> getCombinedAvailablePackages() {
15723 final ArrayMap<String, AndroidPackage> combined =
15724 new ArrayMap<>(request.allPackages.size() + request.scannedPackages.size());
15726 combined.putAll(request.allPackages);
15728 for (ScanResult scanResult : request.scannedPackages.values()) {
15729 combined.put(scanResult.pkgSetting.name, scanResult.request.parsedPackage);
15736 @GuardedBy("mLock")
15737 private static Map<String, ReconciledPackage> reconcilePackagesLocked(
15738 final ReconcileRequest request, KeySetManagerService ksms)
15739 throws ReconcileFailure {
15740 final Map<String, ScanResult> scannedPackages = request.scannedPackages;
15742 final Map<String, ReconciledPackage> result = new ArrayMap<>(scannedPackages.size());
15744 // make a copy of the existing set of packages so we can combine them with incoming packages
15745 final ArrayMap<String, AndroidPackage> combinedPackages =
15746 new ArrayMap<>(request.allPackages.size() + scannedPackages.size());
15748 combinedPackages.putAll(request.allPackages);
15750 final Map<String, LongSparseArray<SharedLibraryInfo>> incomingSharedLibraries =
15753 for (String installPackageName : scannedPackages.keySet()) {
15754 final ScanResult scanResult = scannedPackages.get(installPackageName);
15756 // add / replace existing with incoming packages
15757 combinedPackages.put(scanResult.pkgSetting.name, scanResult.request.parsedPackage);
15759 // in the first pass, we'll build up the set of incoming shared libraries
15760 final List<SharedLibraryInfo> allowedSharedLibInfos =
15761 getAllowedSharedLibInfos(scanResult, request.sharedLibrarySource);
15762 final SharedLibraryInfo staticLib = scanResult.staticSharedLibraryInfo;
15763 if (allowedSharedLibInfos != null) {
15764 for (SharedLibraryInfo info : allowedSharedLibInfos) {
15765 if (!addSharedLibraryToPackageVersionMap(incomingSharedLibraries, info)) {
15766 throw new ReconcileFailure("Static Shared Library " + staticLib.getName()
15767 + " is being installed twice in this set!");
15772 // the following may be null if we're just reconciling on boot (and not during install)
15773 final InstallArgs installArgs = request.installArgs.get(installPackageName);
15774 final PackageInstalledInfo res = request.installResults.get(installPackageName);
15775 final PrepareResult prepareResult = request.preparedPackages.get(installPackageName);
15776 final boolean isInstall = installArgs != null;
15777 if (isInstall && (res == null || prepareResult == null)) {
15778 throw new ReconcileFailure("Reconcile arguments are not balanced for "
15779 + installPackageName + "!");
15782 final DeletePackageAction deletePackageAction;
15783 // we only want to try to delete for non system apps
15784 if (isInstall && prepareResult.replace && !prepareResult.system) {
15785 final boolean killApp = (scanResult.request.scanFlags & SCAN_DONT_KILL_APP) == 0;
15786 final int deleteFlags = PackageManager.DELETE_KEEP_DATA
15787 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
15788 deletePackageAction = mayDeletePackageLocked(res.removedInfo,
15789 prepareResult.originalPs, prepareResult.disabledPs,
15790 deleteFlags, null /* all users */);
15791 if (deletePackageAction == null) {
15792 throw new ReconcileFailure(
15793 PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE,
15794 "May not delete " + installPackageName + " to replace");
15797 deletePackageAction = null;
15800 final int scanFlags = scanResult.request.scanFlags;
15801 final int parseFlags = scanResult.request.parseFlags;
15802 final ParsedPackage parsedPackage = scanResult.request.parsedPackage;
15804 final PackageSetting disabledPkgSetting = scanResult.request.disabledPkgSetting;
15805 final PackageSetting lastStaticSharedLibSetting =
15806 request.lastStaticSharedLibSettings.get(installPackageName);
15807 final PackageSetting signatureCheckPs =
15808 (prepareResult != null && lastStaticSharedLibSetting != null)
15809 ? lastStaticSharedLibSetting
15810 : scanResult.pkgSetting;
15811 boolean removeAppKeySetData = false;
15812 boolean sharedUserSignaturesChanged = false;
15813 SigningDetails signingDetails = null;
15814 if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
15815 if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
15816 // We just determined the app is signed correctly, so bring
15817 // over the latest parsed certs.
15819 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
15820 throw new ReconcileFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15821 "Package " + parsedPackage.getPackageName()
15822 + " upgrade keys do not match the previously installed"
15825 String msg = "System package " + parsedPackage.getPackageName()
15826 + " signature changed; retaining data.";
15827 reportSettingsProblem(Log.WARN, msg);
15830 signingDetails = parsedPackage.getSigningDetails();
15833 final VersionInfo versionInfo = request.versionInfos.get(installPackageName);
15834 final boolean compareCompat = isCompatSignatureUpdateNeeded(versionInfo);
15835 final boolean compareRecover = isRecoverSignatureUpdateNeeded(versionInfo);
15836 final boolean compatMatch = verifySignatures(signatureCheckPs,
15837 disabledPkgSetting, parsedPackage.getSigningDetails(), compareCompat,
15839 // The new KeySets will be re-added later in the scanning process.
15841 removeAppKeySetData = true;
15843 // We just determined the app is signed correctly, so bring
15844 // over the latest parsed certs.
15845 signingDetails = parsedPackage.getSigningDetails();
15848 // if this is is a sharedUser, check to see if the new package is signed by a
15850 // signing certificate than the existing one, and if so, copy over the new
15852 if (signatureCheckPs.sharedUser != null) {
15853 if (parsedPackage.getSigningDetails().hasAncestor(
15854 signatureCheckPs.sharedUser.signatures.mSigningDetails)) {
15855 signatureCheckPs.sharedUser.signatures.mSigningDetails =
15856 parsedPackage.getSigningDetails();
15858 if (signatureCheckPs.sharedUser.signaturesChanged == null) {
15859 signatureCheckPs.sharedUser.signaturesChanged = Boolean.FALSE;
15862 } catch (PackageManagerException e) {
15863 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
15864 throw new ReconcileFailure(e);
15866 signingDetails = parsedPackage.getSigningDetails();
15868 // If the system app is part of a shared user we allow that shared user to
15870 // signatures as well as part of an OTA. We still need to verify that the
15872 // are consistent within the shared user for a given boot, so only allow
15874 // the signatures on the first package scanned for the shared user (i.e. if the
15875 // signaturesChanged state hasn't been initialized yet in SharedUserSetting).
15876 if (signatureCheckPs.sharedUser != null) {
15877 final Signature[] sharedUserSignatures =
15878 signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures;
15879 if (signatureCheckPs.sharedUser.signaturesChanged != null
15880 && compareSignatures(sharedUserSignatures,
15881 parsedPackage.getSigningDetails().signatures)
15882 != PackageManager.SIGNATURE_MATCH) {
15883 if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 29) {
15884 // Mismatched signatures is an error and silently skipping system
15885 // packages will likely break the device in unforeseen ways.
15886 // However, we allow the device to boot anyway because, prior to Q,
15887 // vendors were not expecting the platform to crash in this
15889 // This WILL be a hard failure on any new API levels after Q.
15890 throw new ReconcileFailure(
15891 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
15892 "Signature mismatch for shared user: "
15893 + scanResult.pkgSetting.sharedUser);
15895 // Treat mismatched signatures on system packages using a shared
15897 // fatal for the system overall, rather than just failing to install
15898 // whichever package happened to be scanned later.
15899 throw new IllegalStateException(
15900 "Signature mismatch on system package "
15901 + parsedPackage.getPackageName()
15902 + " for shared user "
15903 + scanResult.pkgSetting.sharedUser);
15907 sharedUserSignaturesChanged = true;
15908 signatureCheckPs.sharedUser.signatures.mSigningDetails =
15909 parsedPackage.getSigningDetails();
15910 signatureCheckPs.sharedUser.signaturesChanged = Boolean.TRUE;
15912 // File a report about this.
15913 String msg = "System package " + parsedPackage.getPackageName()
15914 + " signature changed; retaining data.";
15915 reportSettingsProblem(Log.WARN, msg);
15916 } catch (IllegalArgumentException e) {
15917 // should never happen: certs matched when checking, but not when comparing
15918 // old to new for sharedUser
15919 throw new RuntimeException(
15920 "Signing certificates comparison made on incomparable signing details"
15921 + " but somehow passed verifySignatures!", e);
15925 result.put(installPackageName,
15926 new ReconciledPackage(request, installArgs, scanResult.pkgSetting,
15927 res, request.preparedPackages.get(installPackageName), scanResult,
15928 deletePackageAction, allowedSharedLibInfos, signingDetails,
15929 sharedUserSignaturesChanged, removeAppKeySetData));
15932 for (String installPackageName : scannedPackages.keySet()) {
15933 // Check all shared libraries and map to their actual file path.
15934 // We only do this here for apps not on a system dir, because those
15935 // are the only ones that can fail an install due to this. We
15936 // will take care of the system apps by updating all of their
15937 // library paths after the scan is done. Also during the initial
15938 // scan don't update any libs as we do this wholesale after all
15939 // apps are scanned to avoid dependency based scanning.
15940 final ScanResult scanResult = scannedPackages.get(installPackageName);
15941 if ((scanResult.request.scanFlags & SCAN_BOOTING) != 0
15942 || (scanResult.request.parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
15946 result.get(installPackageName).collectedSharedLibraryInfos =
15947 collectSharedLibraryInfos(scanResult.request.parsedPackage,
15948 combinedPackages, request.sharedLibrarySource,
15949 incomingSharedLibraries);
15951 } catch (PackageManagerException e) {
15952 throw new ReconcileFailure(e.error, e.getMessage());
15960 * Compare the newly scanned package with current system state to see which of its declared
15961 * shared libraries should be allowed to be added to the system.
15963 private static List<SharedLibraryInfo> getAllowedSharedLibInfos(
15964 ScanResult scanResult,
15965 Map<String, LongSparseArray<SharedLibraryInfo>> existingSharedLibraries) {
15966 // Let's used the parsed package as scanResult.pkgSetting may be null
15967 final ParsedPackage parsedPackage = scanResult.request.parsedPackage;
15968 if (scanResult.staticSharedLibraryInfo == null
15969 && scanResult.dynamicSharedLibraryInfos == null) {
15973 // Any app can add new static shared libraries
15974 if (scanResult.staticSharedLibraryInfo != null) {
15975 return Collections.singletonList(scanResult.staticSharedLibraryInfo);
15977 final boolean hasDynamicLibraries = parsedPackage.isSystem()
15978 && scanResult.dynamicSharedLibraryInfos != null;
15979 if (!hasDynamicLibraries) {
15982 final boolean isUpdatedSystemApp = scanResult.pkgSetting.getPkgState()
15983 .isUpdatedSystemApp();
15984 // We may not yet have disabled the updated package yet, so be sure to grab the
15985 // current setting if that's the case.
15986 final PackageSetting updatedSystemPs = isUpdatedSystemApp
15987 ? scanResult.request.disabledPkgSetting == null
15988 ? scanResult.request.oldPkgSetting
15989 : scanResult.request.disabledPkgSetting
15991 if (isUpdatedSystemApp && (updatedSystemPs.pkg == null
15992 || updatedSystemPs.pkg.getLibraryNames() == null)) {
15993 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
15994 + " declares libraries that are not declared on the system image; skipping");
15997 final ArrayList<SharedLibraryInfo> infos =
15998 new ArrayList<>(scanResult.dynamicSharedLibraryInfos.size());
15999 for (SharedLibraryInfo info : scanResult.dynamicSharedLibraryInfos) {
16000 final String name = info.getName();
16001 if (isUpdatedSystemApp) {
16002 // New library entries can only be added through the
16003 // system image. This is important to get rid of a lot
16004 // of nasty edge cases: for example if we allowed a non-
16005 // system update of the app to add a library, then uninstalling
16006 // the update would make the library go away, and assumptions
16007 // we made such as through app install filtering would now
16008 // have allowed apps on the device which aren't compatible
16009 // with it. Better to just have the restriction here, be
16010 // conservative, and create many fewer cases that can negatively
16011 // impact the user experience.
16012 if (!updatedSystemPs.pkg.getLibraryNames().contains(name)) {
16013 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
16014 + " declares library " + name
16015 + " that is not declared on system image; skipping");
16019 if (sharedLibExists(
16020 name, SharedLibraryInfo.VERSION_UNDEFINED, existingSharedLibraries)) {
16021 Slog.w(TAG, "Package " + parsedPackage.getPackageName() + " declares library "
16022 + name + " that already exists; skipping");
16031 * Returns false if the adding shared library already exists in the map and so could not be
16034 private static boolean addSharedLibraryToPackageVersionMap(
16035 Map<String, LongSparseArray<SharedLibraryInfo>> target,
16036 SharedLibraryInfo library) {
16037 final String name = library.getName();
16038 if (target.containsKey(name)) {
16039 if (library.getType() != SharedLibraryInfo.TYPE_STATIC) {
16040 // We've already added this non-version-specific library to the map.
16042 } else if (target.get(name).indexOfKey(library.getLongVersion()) >= 0) {
16043 // We've already added this version of a version-specific library to the map.
16047 target.put(name, new LongSparseArray<>());
16049 target.get(name).put(library.getLongVersion(), library);
16053 @GuardedBy("mLock")
16054 private void commitPackagesLocked(final CommitRequest request) {
16055 // TODO: remove any expected failures from this method; this should only be able to fail due
16056 // to unavoidable errors (I/O, etc.)
16057 for (ReconciledPackage reconciledPkg : request.reconciledPackages.values()) {
16058 final ScanResult scanResult = reconciledPkg.scanResult;
16059 final ScanRequest scanRequest = scanResult.request;
16060 final ParsedPackage parsedPackage = scanRequest.parsedPackage;
16061 final String packageName = parsedPackage.getPackageName();
16062 final PackageInstalledInfo res = reconciledPkg.installResult;
16064 if (reconciledPkg.prepareResult.replace) {
16065 AndroidPackage oldPackage = mPackages.get(packageName);
16067 // Set the update and install times
16068 PackageSetting deletedPkgSetting = getPackageSetting(oldPackage.getPackageName());
16069 reconciledPkg.pkgSetting.firstInstallTime = deletedPkgSetting.firstInstallTime;
16070 reconciledPkg.pkgSetting.lastUpdateTime = System.currentTimeMillis();
16072 if (reconciledPkg.prepareResult.system) {
16073 // Remove existing system package
16074 removePackageLI(oldPackage, true);
16075 if (!disableSystemPackageLPw(oldPackage)) {
16076 // We didn't need to disable the .apk as a current system package,
16077 // which means we are replacing another update that is already
16078 // installed. We need to make sure to delete the older one's .apk.
16079 res.removedInfo.args = createInstallArgsForExisting(
16080 oldPackage.getCodePath(),
16081 oldPackage.getCodePath(),
16082 getAppDexInstructionSets(
16083 AndroidPackageUtils.getPrimaryCpuAbi(oldPackage,
16084 deletedPkgSetting),
16085 AndroidPackageUtils.getSecondaryCpuAbi(oldPackage,
16086 deletedPkgSetting)));
16088 res.removedInfo.args = null;
16092 // Settings will be written during the call to updateSettingsLI().
16093 executeDeletePackageLIF(reconciledPkg.deletePackageAction, packageName,
16094 true, request.mAllUsers, false, parsedPackage);
16095 } catch (SystemDeleteException e) {
16096 if (Build.IS_ENG) {
16097 throw new RuntimeException("Unexpected failure", e);
16098 // ignore; not possible for non-system app
16101 // Successfully deleted the old package; proceed with replace.
16103 // If deleted package lived in a container, give users a chance to
16104 // relinquish resources before killing.
16105 if (oldPackage.isExternalStorage()) {
16106 if (DEBUG_INSTALL) {
16107 Slog.i(TAG, "upgrading pkg " + oldPackage
16108 + " is ASEC-hosted -> UNAVAILABLE");
16110 final int[] uidArray = new int[]{oldPackage.getUid()};
16111 final ArrayList<String> pkgList = new ArrayList<>(1);
16112 pkgList.add(oldPackage.getPackageName());
16113 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16116 // Update the in-memory copy of the previous code paths.
16117 PackageSetting ps1 = mSettings.mPackages.get(
16118 reconciledPkg.prepareResult.existingPackage.getPackageName());
16119 if ((reconciledPkg.installArgs.installFlags & PackageManager.DONT_KILL_APP)
16121 if (ps1.mOldCodePaths == null) {
16122 ps1.mOldCodePaths = new ArraySet<>();
16124 Collections.addAll(ps1.mOldCodePaths, oldPackage.getBaseCodePath());
16125 if (oldPackage.getSplitCodePaths() != null) {
16126 Collections.addAll(ps1.mOldCodePaths, oldPackage.getSplitCodePaths());
16129 ps1.mOldCodePaths = null;
16132 if (reconciledPkg.installResult.returnCode
16133 == PackageManager.INSTALL_SUCCEEDED) {
16134 PackageSetting ps2 = mSettings.getPackageLPr(
16135 parsedPackage.getPackageName());
16137 res.removedInfo.removedForAllUsers = mPackages.get(ps2.name) == null;
16143 AndroidPackage pkg = commitReconciledScanResultLocked(reconciledPkg);
16144 updateSettingsLI(pkg, reconciledPkg.installArgs, request.mAllUsers, res);
16146 final PackageSetting ps = mSettings.mPackages.get(packageName);
16148 res.newUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
16149 ps.setUpdateAvailable(false /*updateAvailable*/);
16151 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16152 updateSequenceNumberLP(ps, res.newUsers);
16153 updateInstantAppInstallerLocked(packageName);
16159 * Installs one or more packages atomically. This operation is broken up into four phases:
16161 * <li><b>Prepare</b>
16162 * <br/>Analyzes any current install state, parses the package and does initial
16163 * validation on it.</li>
16165 * <br/>Interrogates the parsed packages given the context collected in prepare.</li>
16166 * <li><b>Reconcile</b>
16167 * <br/>Validates scanned packages in the context of each other and the current system
16168 * state to ensure that the install will be successful.
16169 * <li><b>Commit</b>
16170 * <br/>Commits all scanned packages and updates system state. This is the only place
16171 * that system state may be modified in the install flow and all predictable errors
16172 * must be determined before this phase.</li>
16175 * Failure at any phase will result in a full failure to install all packages.
16177 @GuardedBy("mInstallLock")
16178 private void installPackagesLI(List<InstallRequest> requests) {
16179 final Map<String, ScanResult> preparedScans = new ArrayMap<>(requests.size());
16180 final Map<String, InstallArgs> installArgs = new ArrayMap<>(requests.size());
16181 final Map<String, PackageInstalledInfo> installResults = new ArrayMap<>(requests.size());
16182 final Map<String, PrepareResult> prepareResults = new ArrayMap<>(requests.size());
16183 final Map<String, VersionInfo> versionInfos = new ArrayMap<>(requests.size());
16184 final Map<String, PackageSetting> lastStaticSharedLibSettings =
16185 new ArrayMap<>(requests.size());
16186 final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size());
16187 boolean success = false;
16189 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackagesLI");
16190 for (InstallRequest request : requests) {
16191 // TODO(b/109941548): remove this once we've pulled everything from it and into
16192 // scan, reconcile or commit.
16193 final PrepareResult prepareResult;
16195 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage");
16197 preparePackageLI(request.args, request.installResult);
16198 } catch (PrepareFailure prepareFailure) {
16199 request.installResult.setError(prepareFailure.error,
16200 prepareFailure.getMessage());
16201 request.installResult.origPackage = prepareFailure.conflictingPackage;
16202 request.installResult.origPermission = prepareFailure.conflictingPermission;
16205 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16207 request.installResult.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16208 request.installResult.installerPackageName =
16209 request.args.installSource.installerPackageName;
16211 final String packageName = prepareResult.packageToScan.getPackageName();
16212 prepareResults.put(packageName, prepareResult);
16213 installResults.put(packageName, request.installResult);
16214 installArgs.put(packageName, request.args);
16216 final ScanResult result = scanPackageTracedLI(
16217 prepareResult.packageToScan, prepareResult.parseFlags,
16218 prepareResult.scanFlags, System.currentTimeMillis(),
16219 request.args.user, request.args.abiOverride);
16220 if (null != preparedScans.put(result.pkgSetting.pkg.getPackageName(), result)) {
16221 request.installResult.setError(
16222 PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE,
16223 "Duplicate package " + result.pkgSetting.pkg.getPackageName()
16224 + " in multi-package install request.");
16227 createdAppId.put(packageName, optimisticallyRegisterAppId(result));
16228 versionInfos.put(result.pkgSetting.pkg.getPackageName(),
16229 getSettingsVersionForPackage(result.pkgSetting.pkg));
16230 if (result.staticSharedLibraryInfo != null) {
16231 final PackageSetting sharedLibLatestVersionSetting =
16232 getSharedLibLatestVersionSetting(result);
16233 if (sharedLibLatestVersionSetting != null) {
16234 lastStaticSharedLibSettings.put(result.pkgSetting.pkg.getPackageName(),
16235 sharedLibLatestVersionSetting);
16238 } catch (PackageManagerException e) {
16239 request.installResult.setError("Scanning Failed.", e);
16243 ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs,
16247 Collections.unmodifiableMap(mPackages), versionInfos,
16248 lastStaticSharedLibSettings);
16249 CommitRequest commitRequest = null;
16250 synchronized (mLock) {
16251 Map<String, ReconciledPackage> reconciledPackages;
16253 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages");
16254 reconciledPackages = reconcilePackagesLocked(
16255 reconcileRequest, mSettings.mKeySetManagerService);
16256 } catch (ReconcileFailure e) {
16257 for (InstallRequest request : requests) {
16258 request.installResult.setError("Reconciliation failed...", e);
16262 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16265 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "commitPackages");
16266 commitRequest = new CommitRequest(reconciledPackages,
16267 mUserManager.getUserIds());
16268 commitPackagesLocked(commitRequest);
16271 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16274 executePostCommitSteps(commitRequest);
16277 for (ScanResult result : preparedScans.values()) {
16278 if (createdAppId.getOrDefault(result.request.parsedPackage.getPackageName(),
16280 cleanUpAppIdCreation(result);
16283 // TODO(patb): create a more descriptive reason than unknown in future release
16284 // mark all non-failure installs as UNKNOWN so we do not treat them as success
16285 for (InstallRequest request : requests) {
16286 if (request.installResult.freezer != null) {
16287 request.installResult.freezer.close();
16289 if (request.installResult.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16290 request.installResult.returnCode = PackageManager.INSTALL_UNKNOWN;
16294 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16299 * On successful install, executes remaining steps after commit completes and the package lock
16300 * is released. These are typically more expensive or require calls to installd, which often
16301 * locks on {@link #mLock}.
16303 private void executePostCommitSteps(CommitRequest commitRequest) {
16304 for (ReconciledPackage reconciledPkg : commitRequest.reconciledPackages.values()) {
16305 final boolean instantApp = ((reconciledPkg.scanResult.request.scanFlags
16306 & PackageManagerService.SCAN_AS_INSTANT_APP) != 0);
16307 final AndroidPackage pkg = reconciledPkg.pkgSetting.pkg;
16308 final String packageName = pkg.getPackageName();
16309 final boolean onIncremental = mIncrementalManager != null
16310 && isIncrementalPath(pkg.getCodePath());
16311 prepareAppDataAfterInstallLIF(pkg);
16312 if (reconciledPkg.prepareResult.clearCodeCache) {
16313 clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
16314 | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16316 if (reconciledPkg.prepareResult.replace) {
16317 mDexManager.notifyPackageUpdated(pkg.getPackageName(),
16318 pkg.getBaseCodePath(), pkg.getSplitCodePaths());
16321 // Prepare the application profiles for the new code paths.
16322 // This needs to be done before invoking dexopt so that any install-time profile
16323 // can be used for optimizations.
16324 mArtManagerService.prepareAppProfiles(
16326 resolveUserIds(reconciledPkg.installArgs.user.getIdentifier()),
16327 /* updateReferenceProfileContent= */ true);
16329 // Check whether we need to dexopt the app.
16331 // NOTE: it is IMPORTANT to call dexopt:
16332 // - after doRename which will sync the package data from AndroidPackage and
16333 // its corresponding ApplicationInfo.
16334 // - after installNewPackageLIF or replacePackageLIF which will update result with the
16335 // uid of the application (pkg.applicationInfo.uid).
16336 // This update happens in place!
16338 // We only need to dexopt if the package meets ALL of the following conditions:
16339 // 1) it is not an instant app or if it is then dexopt is enabled via gservices.
16340 // 2) it is not debuggable.
16341 // 3) it is not on Incremental File System.
16343 // Note that we do not dexopt instant apps by default. dexopt can take some time to
16344 // complete, so we skip this step during installation. Instead, we'll take extra time
16345 // the first time the instant app starts. It's preferred to do it this way to provide
16346 // continuous progress to the useur instead of mysteriously blocking somewhere in the
16347 // middle of running an instant app. The default behaviour can be overridden
16349 final boolean performDexopt =
16350 (!instantApp || Global.getInt(mContext.getContentResolver(),
16351 Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
16352 && !pkg.isDebuggable()
16353 && (!onIncremental);
16355 if (performDexopt) {
16356 // Compile the layout resources.
16357 if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
16358 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "compileLayouts");
16359 mViewCompiler.compileLayouts(pkg);
16360 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16363 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
16364 // Do not run PackageDexOptimizer through the local performDexOpt
16365 // method because `pkg` may not be in `mPackages` yet.
16367 // Also, don't fail application installs if the dexopt step fails.
16368 DexoptOptions dexoptOptions = new DexoptOptions(packageName,
16370 DexoptOptions.DEXOPT_BOOT_COMPLETE
16371 | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE);
16372 ScanResult result = reconciledPkg.scanResult;
16374 // This mirrors logic from commitReconciledScanResultLocked, where the library files
16375 // needed for dexopt are assigned.
16376 // TODO: Fix this to have 1 mutable PackageSetting for scan/install. If the previous
16377 // setting needs to be passed to have a comparison, hide it behind an immutable
16378 // interface. There's no good reason to have 3 different ways to access the real
16379 // PackageSetting object, only one of which is actually correct.
16380 PackageSetting realPkgSetting = result.existingSettingCopied
16381 ? result.request.pkgSetting : result.pkgSetting;
16382 if (realPkgSetting == null) {
16383 realPkgSetting = reconciledPkg.pkgSetting;
16386 // Unfortunately, the updated system app flag is only tracked on this PackageSetting
16387 boolean isUpdatedSystemApp = reconciledPkg.pkgSetting.getPkgState()
16388 .isUpdatedSystemApp();
16390 realPkgSetting.getPkgState().setUpdatedSystemApp(isUpdatedSystemApp);
16392 mPackageDexOptimizer.performDexOpt(pkg, realPkgSetting,
16393 null /* instructionSets */,
16394 getOrCreateCompilerPackageStats(pkg),
16395 mDexManager.getPackageUseInfoOrDefault(packageName),
16397 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16400 // Notify BackgroundDexOptService that the package has been changed.
16401 // If this is an update of a package which used to fail to compile,
16402 // BackgroundDexOptService will remove it from its blacklist.
16403 // TODO: Layering violation
16404 BackgroundDexOptService.notifyPackageChanged(packageName);
16409 * The set of data needed to successfully install the prepared package. This includes data that
16410 * will be used to scan and reconcile the package.
16412 private static class PrepareResult {
16413 public final boolean replace;
16414 public final int scanFlags;
16415 public final int parseFlags;
16416 @Nullable /* The original Package if it is being replaced, otherwise {@code null} */
16417 public final AndroidPackage existingPackage;
16418 public final ParsedPackage packageToScan;
16419 public final boolean clearCodeCache;
16420 public final boolean system;
16421 public final PackageSetting originalPs;
16422 public final PackageSetting disabledPs;
16424 private PrepareResult(boolean replace, int scanFlags,
16425 int parseFlags, AndroidPackage existingPackage,
16426 ParsedPackage packageToScan, boolean clearCodeCache, boolean system,
16427 PackageSetting originalPs, PackageSetting disabledPs) {
16428 this.replace = replace;
16429 this.scanFlags = scanFlags;
16430 this.parseFlags = parseFlags;
16431 this.existingPackage = existingPackage;
16432 this.packageToScan = packageToScan;
16433 this.clearCodeCache = clearCodeCache;
16434 this.system = system;
16435 this.originalPs = originalPs;
16436 this.disabledPs = disabledPs;
16440 private static class PrepareFailure extends PackageManagerException {
16442 public String conflictingPackage;
16443 public String conflictingPermission;
16445 PrepareFailure(int error) {
16446 super(error, "Failed to prepare for install.");
16449 PrepareFailure(int error, String detailMessage) {
16450 super(error, detailMessage);
16453 PrepareFailure(String message, Exception e) {
16454 super(e instanceof PackageParserException
16455 ? ((PackageParserException) e).error
16456 : ((PackageManagerException) e).error,
16457 ExceptionUtils.getCompleteMessage(message, e));
16460 PrepareFailure conflictsWithExistingPermission(String conflictingPermission,
16461 String conflictingPackage) {
16462 this.conflictingPermission = conflictingPermission;
16463 this.conflictingPackage = conflictingPackage;
16468 @GuardedBy("mInstallLock")
16469 private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res)
16470 throws PrepareFailure {
16471 final int installFlags = args.installFlags;
16472 final File tmpPackageFile = new File(args.getCodePath());
16473 final boolean onExternal = args.volumeUuid != null;
16474 final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
16475 final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
16476 final boolean virtualPreload =
16477 ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
16478 @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
16479 if (args.move != null) {
16480 // moving a complete application; perform an initial scan on the new install location
16481 scanFlags |= SCAN_INITIAL;
16483 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
16484 scanFlags |= SCAN_DONT_KILL_APP;
16487 scanFlags |= SCAN_AS_INSTANT_APP;
16490 scanFlags |= SCAN_AS_FULL_APP;
16492 if (virtualPreload) {
16493 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
16496 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
16499 if (instantApp && onExternal) {
16500 Slog.i(TAG, "Incompatible ephemeral install; external=" + onExternal);
16501 throw new PrepareFailure(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16504 // Retrieve PackageSettings and parse package
16505 @ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
16506 | PackageParser.PARSE_ENFORCE_CODE
16507 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16509 PackageParser2 pp = new PackageParser2(mSeparateProcesses, false, mMetrics, null,
16510 mPackageParserCallback);
16512 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
16513 ParsedPackage parsedPackage;
16515 parsedPackage = pp.parsePackage(tmpPackageFile, parseFlags, false);
16516 AndroidPackageUtils.validatePackageDexMetadata(parsedPackage);
16517 } catch (PackageParserException e) {
16518 throw new PrepareFailure("Failed parse during installPackageLI", e);
16520 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16523 // Instant apps have several additional install-time checks.
16525 if (parsedPackage.getTargetSdkVersion() < Build.VERSION_CODES.O) {
16526 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
16527 + " does not target at least O");
16528 throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
16529 "Instant app package must target at least O");
16531 if (parsedPackage.getSharedUserId() != null) {
16532 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
16533 + " may not declare sharedUserId.");
16534 throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
16535 "Instant app package may not declare a sharedUserId");
16539 if (parsedPackage.isStaticSharedLibrary()) {
16540 // Static shared libraries have synthetic package names
16541 renameStaticSharedLibraryPackage(parsedPackage);
16543 // No static shared libs on external storage
16545 Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
16546 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16547 "Packages declaring static-shared libs cannot be updated");
16551 String pkgName = res.name = parsedPackage.getPackageName();
16552 if (parsedPackage.isTestOnly()) {
16553 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
16554 throw new PrepareFailure(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
16559 // either use what we've been given or parse directly from the APK
16560 if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
16561 parsedPackage.setSigningDetails(args.signingDetails);
16563 // TODO(b/136132412): skip for Incremental installation
16564 parsedPackage.setSigningDetails(
16565 ParsingPackageUtils.collectCertificates(parsedPackage, false /* skipVerify */));
16567 } catch (PackageParserException e) {
16568 throw new PrepareFailure("Failed collect during installPackageLI", e);
16571 if (instantApp && parsedPackage.getSigningDetails().signatureSchemeVersion
16572 < SignatureSchemeVersion.SIGNING_BLOCK_V2) {
16573 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
16574 + " is not signed with at least APK Signature Scheme v2");
16575 throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
16576 "Instant app package must be signed with APK Signature Scheme v2 or greater");
16579 // Get rid of all references to package scan path via parser.
16581 boolean systemApp = false;
16582 boolean replace = false;
16583 synchronized (mLock) {
16584 // Check if installing already existing package
16585 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16586 String oldName = mSettings.getRenamedPackageLPr(pkgName);
16587 if (parsedPackage.getOriginalPackages().contains(oldName)
16588 && mPackages.containsKey(oldName)) {
16589 // This package is derived from an original package,
16590 // and this device has been updating from that original
16591 // name. We must continue using the original name, so
16592 // rename the new package here.
16593 parsedPackage.setPackageName(oldName);
16594 pkgName = parsedPackage.getPackageName();
16596 if (DEBUG_INSTALL) {
16597 Slog.d(TAG, "Replacing existing renamed package: oldName="
16598 + oldName + " pkgName=" + pkgName);
16600 } else if (mPackages.containsKey(pkgName)) {
16601 // This package, under its official name, already exists
16602 // on the device; we should replace it.
16604 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
16608 // Prevent apps opting out from runtime permissions
16609 AndroidPackage oldPackage = mPackages.get(pkgName);
16610 final int oldTargetSdk = oldPackage.getTargetSdkVersion();
16611 final int newTargetSdk = parsedPackage.getTargetSdkVersion();
16612 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
16613 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
16614 throw new PrepareFailure(
16615 PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
16616 "Package " + parsedPackage.getPackageName()
16617 + " new target SDK " + newTargetSdk
16618 + " doesn't support runtime permissions but the old"
16619 + " target SDK " + oldTargetSdk + " does.");
16621 // Prevent persistent apps from being updated
16622 if (oldPackage.isPersistent()
16623 && ((installFlags & PackageManager.INSTALL_STAGED) == 0)) {
16624 throw new PrepareFailure(PackageManager.INSTALL_FAILED_INVALID_APK,
16625 "Package " + oldPackage.getPackageName() + " is a persistent app. "
16626 + "Persistent apps are not updateable.");
16631 PackageSetting ps = mSettings.mPackages.get(pkgName);
16633 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
16635 // Static shared libs have same package with different versions where
16636 // we internally use a synthetic package name to allow multiple versions
16637 // of the same package, therefore we need to compare signatures against
16638 // the package setting for the latest library version.
16639 PackageSetting signatureCheckPs = ps;
16640 if (parsedPackage.isStaticSharedLibrary()) {
16641 SharedLibraryInfo libraryInfo = getLatestSharedLibraVersionLPr(parsedPackage);
16642 if (libraryInfo != null) {
16643 signatureCheckPs = mSettings.getPackageLPr(libraryInfo.getPackageName());
16647 // Quick sanity check that we're signed correctly if updating;
16648 // we'll check this again later when scanning, but we want to
16649 // bail early here before tripping over redefined permissions.
16650 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16651 if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
16652 if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
16653 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
16654 + parsedPackage.getPackageName() + " upgrade keys do not match the "
16655 + "previously installed version");
16659 final boolean compareCompat = isCompatSignatureUpdateNeeded(parsedPackage);
16660 final boolean compareRecover = isRecoverSignatureUpdateNeeded(
16662 // We don't care about disabledPkgSetting on install for now.
16663 final boolean compatMatch = verifySignatures(signatureCheckPs, null,
16664 parsedPackage.getSigningDetails(), compareCompat, compareRecover);
16665 // The new KeySets will be re-added later in the scanning process.
16667 synchronized (mLock) {
16668 ksms.removeAppKeySetDataLPw(parsedPackage.getPackageName());
16671 } catch (PackageManagerException e) {
16672 throw new PrepareFailure(e.error, e.getMessage());
16676 if (ps.pkg != null) {
16677 systemApp = ps.pkg.isSystem();
16679 res.origUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
16683 int N = ArrayUtils.size(parsedPackage.getPermissions());
16684 for (int i = N - 1; i >= 0; i--) {
16685 final ParsedPermission perm = parsedPackage.getPermissions().get(i);
16686 final BasePermission bp = mPermissionManager.getPermissionTEMP(perm.getName());
16688 // Don't allow anyone but the system to define ephemeral permissions.
16689 if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
16691 Slog.w(TAG, "Non-System package " + parsedPackage.getPackageName()
16692 + " attempting to delcare ephemeral permission "
16693 + perm.getName() + "; Removing ephemeral.");
16694 perm.setProtectionLevel(perm.getProtectionLevel() & ~PermissionInfo.PROTECTION_FLAG_INSTANT);
16697 // Check whether the newly-scanned package wants to define an already-defined perm
16699 // If the defining package is signed with our cert, it's okay. This
16700 // also includes the "updating the same package" case, of course.
16701 // "updating same package" could also involve key-rotation.
16702 final boolean sigsOk;
16703 final String sourcePackageName = bp.getSourcePackageName();
16704 final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
16705 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16706 if (sourcePackageName.equals(parsedPackage.getPackageName())
16707 && (ksms.shouldCheckUpgradeKeySetLocked(
16708 sourcePackageSetting, scanFlags))) {
16709 sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, parsedPackage);
16712 // in the event of signing certificate rotation, we need to see if the
16713 // package's certificate has rotated from the current one, or if it is an
16714 // older certificate with which the current is ok with sharing permissions
16715 if (sourcePackageSetting.signatures.mSigningDetails.checkCapability(
16716 parsedPackage.getSigningDetails(),
16717 PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
16719 } else if (parsedPackage.getSigningDetails().checkCapability(
16720 sourcePackageSetting.signatures.mSigningDetails,
16721 PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
16723 // the scanned package checks out, has signing certificate rotation
16724 // history, and is newer; bring it over
16725 sourcePackageSetting.signatures.mSigningDetails =
16726 parsedPackage.getSigningDetails();
16733 // If the owning package is the system itself, we log but allow
16734 // install to proceed; we fail the install on all other permission
16736 if (!sourcePackageName.equals("android")) {
16737 throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
16738 + parsedPackage.getPackageName()
16739 + " attempting to redeclare permission "
16740 + perm.getName() + " already owned by "
16741 + sourcePackageName)
16742 .conflictsWithExistingPermission(perm.getName(),
16743 sourcePackageName);
16745 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
16746 + " attempting to redeclare system permission "
16747 + perm.getName() + "; ignoring new declaration");
16748 parsedPackage.removePermission(i);
16750 } else if (!PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())) {
16751 // Prevent apps to change protection level to dangerous from any other
16752 // type as this would allow a privilege escalation where an app adds a
16753 // normal/signature permission in other app's group and later redefines
16754 // it as dangerous leading to the group auto-grant.
16755 if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_MASK_BASE)
16756 == PermissionInfo.PROTECTION_DANGEROUS) {
16757 if (bp != null && !bp.isRuntime()) {
16758 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
16759 + " trying to change a non-runtime permission "
16761 + " to runtime; keeping old protection level");
16762 perm.setProtectionLevel(bp.getProtectionLevel());
16772 // Abort update; system app can't be replaced with app on sdcard
16773 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16774 "Cannot install updates to system apps on sdcard");
16775 } else if (instantApp) {
16776 // Abort update; system app can't be replaced with an instant app
16777 throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
16778 "Cannot update a system app with an instant app");
16782 if (args.move != null) {
16783 // We did an in-place move, so dex is ready to roll
16784 scanFlags |= SCAN_NO_DEX;
16785 scanFlags |= SCAN_MOVE;
16787 synchronized (mLock) {
16788 final PackageSetting ps = mSettings.mPackages.get(pkgName);
16790 res.setError(INSTALL_FAILED_INTERNAL_ERROR,
16791 "Missing settings for moved package " + pkgName);
16794 // We moved the entire application as-is, so bring over the
16795 // previously derived ABI information.
16796 parsedPackage.setPrimaryCpuAbi(ps.primaryCpuAbiString)
16797 .setSecondaryCpuAbi(ps.secondaryCpuAbiString);
16801 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
16802 scanFlags |= SCAN_NO_DEX;
16805 final boolean extractNativeLibs = !AndroidPackageUtils.isLibrary(parsedPackage);
16806 PackageSetting pkgSetting;
16807 synchronized (mLock) {
16808 pkgSetting = mSettings.getPackageLPr(pkgName);
16810 String abiOverride =
16811 (pkgSetting == null || TextUtils.isEmpty(pkgSetting.cpuAbiOverrideString)
16812 ? args.abiOverride : pkgSetting.cpuAbiOverrideString);
16813 boolean isUpdatedSystemAppFromExistingSetting = pkgSetting != null
16814 && pkgSetting.getPkgState().isUpdatedSystemApp();
16815 AndroidPackage oldPackage = mPackages.get(pkgName);
16816 boolean isUpdatedSystemAppInferred = oldPackage != null && oldPackage.isSystem();
16817 final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
16818 derivedAbi = mInjector.getAbiHelper().derivePackageAbi(parsedPackage,
16819 isUpdatedSystemAppFromExistingSetting || isUpdatedSystemAppInferred,
16820 abiOverride, extractNativeLibs);
16821 derivedAbi.first.applyTo(parsedPackage);
16822 derivedAbi.second.applyTo(parsedPackage);
16823 } catch (PackageManagerException pme) {
16824 Slog.e(TAG, "Error deriving application ABI", pme);
16825 throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
16826 "Error deriving application ABI");
16830 if (!args.doRename(res.returnCode, parsedPackage)) {
16831 throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
16835 setUpFsVerityIfPossible(parsedPackage);
16836 } catch (InstallerException | IOException | DigestException | NoSuchAlgorithmException e) {
16837 throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
16838 "Failed to set up verity: " + e);
16842 startIntentFilterVerifications(args.user.getIdentifier(), replace, parsedPackage);
16844 if (DEBUG_DOMAIN_VERIFICATION) {
16845 Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);
16848 final PackageFreezer freezer =
16849 freezePackageForInstall(pkgName, installFlags, "installPackageLI");
16850 boolean shouldCloseFreezerBeforeReturn = true;
16852 final AndroidPackage existingPackage;
16853 String renamedPackage = null;
16854 boolean sysPkg = false;
16855 int targetScanFlags = scanFlags;
16856 int targetParseFlags = parseFlags;
16857 final PackageSetting ps;
16858 final PackageSetting disabledPs;
16859 final PackageSetting[] childPackages;
16861 if (parsedPackage.isStaticSharedLibrary()) {
16862 // Static libs have a synthetic package name containing the version
16863 // and cannot be updated as an update would get a new package name,
16864 // unless this is the exact same version code which is useful for
16866 AndroidPackage existingPkg = mPackages.get(parsedPackage.getPackageName());
16867 if (existingPkg != null
16868 && existingPkg.getLongVersionCode()
16869 != parsedPackage.getLongVersionCode()) {
16870 throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PACKAGE,
16871 "Packages declaring "
16872 + "static-shared libs cannot be updated");
16876 final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16878 final AndroidPackage oldPackage;
16879 final String pkgName11 = parsedPackage.getPackageName();
16880 final int[] allUsers;
16881 final int[] installedUsers;
16883 synchronized (mLock) {
16884 oldPackage = mPackages.get(pkgName11);
16885 existingPackage = oldPackage;
16886 if (DEBUG_INSTALL) {
16887 // TODO(b/135203078): PackageImpl.toString()
16889 "replacePackageLI: new=" + parsedPackage + ", old=" + oldPackage);
16892 ps = mSettings.mPackages.get(pkgName11);
16893 disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
16895 // verify signatures are valid
16896 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16897 if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
16898 if (!ksms.checkUpgradeKeySetLocked(ps, parsedPackage)) {
16899 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16900 "New package not signed by keys specified by upgrade-keysets: "
16904 // default to original signature matching
16905 if (!parsedPackage.getSigningDetails().checkCapability(
16906 oldPackage.getSigningDetails(),
16907 SigningDetails.CertCapabilities.INSTALLED_DATA)
16908 && !oldPackage.getSigningDetails().checkCapability(
16909 parsedPackage.getSigningDetails(),
16910 SigningDetails.CertCapabilities.ROLLBACK)) {
16911 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16912 "New package has a different signature: " + pkgName11);
16916 // don't allow a system upgrade unless the upgrade hash matches
16917 if (oldPackage.getRestrictUpdateHash() != null && oldPackage.isSystem()) {
16918 final byte[] digestBytes;
16920 final MessageDigest digest = MessageDigest.getInstance("SHA-512");
16921 updateDigest(digest, new File(parsedPackage.getBaseCodePath()));
16922 if (!ArrayUtils.isEmpty(parsedPackage.getSplitCodePaths())) {
16923 for (String path : parsedPackage.getSplitCodePaths()) {
16924 updateDigest(digest, new File(path));
16927 digestBytes = digest.digest();
16928 } catch (NoSuchAlgorithmException | IOException e) {
16929 throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
16930 "Could not compute hash: " + pkgName11);
16932 if (!Arrays.equals(oldPackage.getRestrictUpdateHash(), digestBytes)) {
16933 throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
16934 "New package fails restrict-update check: " + pkgName11);
16936 // retain upgrade restriction
16937 parsedPackage.setRestrictUpdateHash(oldPackage.getRestrictUpdateHash());
16940 // Check for shared user id changes
16941 String invalidPackageName = null;
16942 if (!Objects.equals(oldPackage.getSharedUserId(),
16943 parsedPackage.getSharedUserId())) {
16944 invalidPackageName = parsedPackage.getPackageName();
16947 if (invalidPackageName != null) {
16948 throw new PrepareFailure(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
16949 "Package " + invalidPackageName + " tried to change user "
16950 + oldPackage.getSharedUserId());
16953 // In case of rollback, remember per-user/profile install state
16954 allUsers = mUserManager.getUserIds();
16955 installedUsers = ps.queryInstalledUsers(allUsers, true);
16958 // don't allow an upgrade from full to ephemeral
16959 if (isInstantApp) {
16960 if (args.user == null || args.user.getIdentifier() == UserHandle.USER_ALL) {
16961 for (int currentUser : allUsers) {
16962 if (!ps.getInstantApp(currentUser)) {
16963 // can't downgrade from full to instant
16965 "Can't replace full app with instant app: " + pkgName11
16966 + " for user: " + currentUser);
16967 throw new PrepareFailure(
16968 PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16971 } else if (!ps.getInstantApp(args.user.getIdentifier())) {
16972 // can't downgrade from full to instant
16973 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName11
16974 + " for user: " + args.user.getIdentifier());
16975 throw new PrepareFailure(
16976 PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16981 // Update what is removed
16982 res.removedInfo = new PackageRemovedInfo(this);
16983 res.removedInfo.uid = oldPackage.getUid();
16984 res.removedInfo.removedPackage = oldPackage.getPackageName();
16985 res.removedInfo.installerPackageName = ps.installSource.installerPackageName;
16986 res.removedInfo.isStaticSharedLib = parsedPackage.getStaticSharedLibName() != null;
16987 res.removedInfo.isUpdate = true;
16988 res.removedInfo.origUsers = installedUsers;
16989 res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
16990 for (int i = 0; i < installedUsers.length; i++) {
16991 final int userId = installedUsers[i];
16992 res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
16995 sysPkg = oldPackage.isSystem();
16997 // Set the system/privileged/oem/vendor/product flags as needed
16998 final boolean privileged = oldPackage.isPrivileged();
16999 final boolean oem = oldPackage.isOem();
17000 final boolean vendor = oldPackage.isVendor();
17001 final boolean product = oldPackage.isProduct();
17002 final boolean odm = oldPackage.isOdm();
17003 final boolean systemExt = oldPackage.isSystemExt();
17004 final @ParseFlags int systemParseFlags = parseFlags;
17005 final @ScanFlags int systemScanFlags = scanFlags
17007 | (privileged ? SCAN_AS_PRIVILEGED : 0)
17008 | (oem ? SCAN_AS_OEM : 0)
17009 | (vendor ? SCAN_AS_VENDOR : 0)
17010 | (product ? SCAN_AS_PRODUCT : 0)
17011 | (odm ? SCAN_AS_ODM : 0)
17012 | (systemExt ? SCAN_AS_SYSTEM_EXT : 0);
17014 if (DEBUG_INSTALL) {
17015 Slog.d(TAG, "replaceSystemPackageLI: new=" + parsedPackage
17016 + ", old=" + oldPackage);
17018 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17019 targetParseFlags = systemParseFlags;
17020 targetScanFlags = systemScanFlags;
17021 } else { // non system replace
17023 if (DEBUG_INSTALL) {
17025 "replaceNonSystemPackageLI: new=" + parsedPackage + ", old="
17029 } else { // new package install
17033 existingPackage = null;
17034 // Remember this for later, in case we need to rollback this install
17035 String pkgName1 = parsedPackage.getPackageName();
17037 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + parsedPackage);
17039 // TODO(patb): MOVE TO RECONCILE
17040 synchronized (mLock) {
17041 renamedPackage = mSettings.getRenamedPackageLPr(pkgName1);
17042 if (renamedPackage != null) {
17043 // A package with the same name is already installed, though
17044 // it has been renamed to an older name. The package we
17045 // are trying to install should be installed as an update to
17046 // the existing one, but that has not been requested, so bail.
17047 throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS,
17048 "Attempt to re-install " + pkgName1
17049 + " without first uninstalling package running as "
17052 if (mPackages.containsKey(pkgName1)) {
17053 // Don't allow installation over an existing package with the same name.
17054 throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS,
17055 "Attempt to re-install " + pkgName1
17056 + " without first uninstalling.");
17060 // we're passing the freezer back to be closed in a later phase of install
17061 shouldCloseFreezerBeforeReturn = false;
17063 return new PrepareResult(replace, targetScanFlags, targetParseFlags,
17064 existingPackage, parsedPackage, replace /* clearCodeCache */, sysPkg,
17067 res.freezer = freezer;
17068 if (shouldCloseFreezerBeforeReturn) {
17075 * Set up fs-verity for the given package if possible. This requires a feature flag of system
17076 * property to be enabled only if the kernel supports fs-verity.
17078 * <p>When the feature flag is set to legacy mode, only APK is supported (with some experimental
17079 * kernel patches). In normal mode, all file format can be supported.
17081 private void setUpFsVerityIfPossible(AndroidPackage pkg) throws InstallerException,
17082 PrepareFailure, IOException, DigestException, NoSuchAlgorithmException {
17083 final boolean standardMode = PackageManagerServiceUtils.isApkVerityEnabled();
17084 final boolean legacyMode = PackageManagerServiceUtils.isLegacyApkVerityEnabled();
17085 if (!standardMode && !legacyMode) {
17089 // Collect files we care for fs-verity setup.
17090 ArrayMap<String, String> fsverityCandidates = new ArrayMap<>();
17092 synchronized (mLock) {
17093 final PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
17094 if (ps != null && ps.isPrivileged()) {
17095 fsverityCandidates.put(pkg.getBaseCodePath(), null);
17096 if (pkg.getSplitCodePaths() != null) {
17097 for (String splitPath : pkg.getSplitCodePaths()) {
17098 fsverityCandidates.put(splitPath, null);
17104 // NB: These files will become only accessible if the signing key is loaded in kernel's
17105 // .fs-verity keyring.
17106 fsverityCandidates.put(pkg.getBaseCodePath(),
17107 VerityUtils.getFsveritySignatureFilePath(pkg.getBaseCodePath()));
17109 final String dmPath = DexMetadataHelper.buildDexMetadataPathForApk(
17110 pkg.getBaseCodePath());
17111 if (new File(dmPath).exists()) {
17112 fsverityCandidates.put(dmPath, VerityUtils.getFsveritySignatureFilePath(dmPath));
17115 if (pkg.getSplitCodePaths() != null) {
17116 for (String path : pkg.getSplitCodePaths()) {
17117 fsverityCandidates.put(path, VerityUtils.getFsveritySignatureFilePath(path));
17119 final String splitDmPath = DexMetadataHelper.buildDexMetadataPathForApk(path);
17120 if (new File(splitDmPath).exists()) {
17121 fsverityCandidates.put(splitDmPath,
17122 VerityUtils.getFsveritySignatureFilePath(splitDmPath));
17128 for (Map.Entry<String, String> entry : fsverityCandidates.entrySet()) {
17129 final String filePath = entry.getKey();
17130 final String signaturePath = entry.getValue();
17133 // fs-verity is optional for now. Only set up if signature is provided.
17134 if (new File(signaturePath).exists() && !VerityUtils.hasFsverity(filePath)) {
17136 VerityUtils.setUpFsverity(filePath, signaturePath);
17137 } catch (IOException e) {
17138 throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
17139 "Failed to enable fs-verity: " + e);
17145 // In legacy mode, fs-verity can only be enabled by process with CAP_SYS_ADMIN.
17146 final VerityUtils.SetupResult result = VerityUtils.generateApkVeritySetupData(filePath);
17147 if (result.isOk()) {
17148 if (Build.IS_DEBUGGABLE) Slog.i(TAG, "Enabling verity to " + filePath);
17149 final FileDescriptor fd = result.getUnownedFileDescriptor();
17151 final byte[] rootHash = VerityUtils.generateApkVerityRootHash(filePath);
17153 // A file may already have fs-verity, e.g. when reused during a split
17154 // install. If the measurement succeeds, no need to attempt to set up.
17155 mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
17156 } catch (InstallerException e) {
17157 mInstaller.installApkVerity(filePath, fd, result.getContentSize());
17158 mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
17161 IoUtils.closeQuietly(fd);
17163 } else if (result.isFailed()) {
17164 throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
17165 "Failed to generate verity");
17170 private void startIntentFilterVerifications(int userId, boolean replacing, AndroidPackage pkg) {
17171 if (mIntentFilterVerifierComponent == null) {
17172 Slog.w(TAG, "No IntentFilter verification will not be done as "
17173 + "there is no IntentFilterVerifier available!");
17177 final int verifierUid = getPackageUid(
17178 mIntentFilterVerifierComponent.getPackageName(),
17179 MATCH_DEBUG_TRIAGED_MISSING,
17180 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
17182 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17183 msg.obj = new IFVerificationParams(
17184 pkg.getPackageName(),
17185 pkg.isHasDomainUrls(),
17186 pkg.getActivities(),
17191 mHandler.sendMessage(msg);
17194 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
17195 String packageName,
17196 boolean hasDomainUrls,
17197 List<ParsedActivity> activities) {
17198 int size = activities.size();
17200 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17201 "No activity, so no need to verify any IntentFilter!");
17205 if (!hasDomainUrls) {
17206 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17207 "No domain URLs, so no need to verify any IntentFilter!");
17211 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
17212 + " if any IntentFilter from the " + size
17213 + " Activities needs verification ...");
17216 boolean handlesWebUris = false;
17217 final boolean alreadyVerified;
17218 synchronized (mLock) {
17219 // If this is a new install and we see that we've already run verification for this
17220 // package, we have nothing to do: it means the state was restored from backup.
17221 final IntentFilterVerificationInfo ivi =
17222 mSettings.getIntentFilterVerificationLPr(packageName);
17223 alreadyVerified = (ivi != null);
17224 if (!replacing && alreadyVerified) {
17225 if (DEBUG_DOMAIN_VERIFICATION) {
17226 Slog.i(TAG, "Package " + packageName + " already verified: status="
17227 + ivi.getStatusString());
17232 // If any filters need to be verified, then all need to be. In addition, we need to
17233 // know whether an updating app has any web navigation intent filters, to re-
17234 // examine handling policy even if not re-verifying.
17235 boolean needToVerify = false;
17236 for (ParsedActivity a : activities) {
17237 for (ParsedIntentInfo filter : a.getIntents()) {
17238 if (filter.handlesWebUris(true)) {
17239 handlesWebUris = true;
17241 if (filter.needsVerification()
17242 && needsNetworkVerificationLPr(a.getPackageName())) {
17243 if (DEBUG_DOMAIN_VERIFICATION) {
17245 "Intent filter needs verification, so processing all filters");
17247 needToVerify = true;
17248 // It's safe to break out here because filter.needsVerification()
17249 // can only be true if filter.handlesWebUris(true) returns true, so
17250 // we've already noted that.
17256 // Note whether this app publishes any web navigation handling support at all,
17257 // and whether there are any web-nav filters that fit the profile for running
17258 // a verification pass now.
17259 if (needToVerify) {
17260 final int verificationId = mIntentFilterVerificationToken++;
17261 for (ParsedActivity a : activities) {
17262 for (ParsedIntentInfo filter : a.getIntents()) {
17263 if (filter.handlesWebUris(true)
17264 && needsNetworkVerificationLPr(a.getPackageName())) {
17265 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17266 "Verification needed for IntentFilter:" + filter.toString());
17267 mIntentFilterVerifier.addOneIntentFilterVerification(
17268 verifierUid, userId, verificationId, filter, packageName);
17277 // count > 0 means that we're running a full verification pass
17278 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17279 + " IntentFilter verification" + (count > 1 ? "s" : "")
17280 + " for userId:" + userId);
17281 mIntentFilterVerifier.startVerifications(userId);
17282 } else if (alreadyVerified && handlesWebUris) {
17283 // App used autoVerify in the past, no longer does, but still handles web
17284 // navigation starts.
17285 if (DEBUG_DOMAIN_VERIFICATION) {
17286 Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy");
17288 synchronized (mLock) {
17289 clearIntentFilterVerificationsLPw(packageName, userId);
17292 if (DEBUG_DOMAIN_VERIFICATION) {
17293 Slog.d(TAG, "No web filters or no prior verify policy for " + packageName);
17298 @GuardedBy("mLock")
17299 private boolean needsNetworkVerificationLPr(String packageName) {
17300 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17305 int status = ivi.getStatus();
17307 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17308 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
17309 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17318 private static boolean isExternal(PackageSetting ps) {
17319 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17322 private static boolean isSystemApp(PackageSetting ps) {
17323 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17326 private static boolean isUpdatedSystemApp(PackageSetting ps) {
17327 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17330 private VersionInfo getSettingsVersionForPackage(AndroidPackage pkg) {
17331 if (pkg.isExternalStorage()) {
17332 if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
17333 return mSettings.getExternalVersion();
17335 return mSettings.findOrCreateVersion(pkg.getVolumeUuid());
17338 return mSettings.getInternalVersion();
17343 public void deletePackageAsUser(String packageName, int versionCode,
17344 IPackageDeleteObserver observer, int userId, int flags) {
17345 deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17346 new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17350 public void deletePackageVersioned(VersionedPackage versionedPackage,
17351 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17352 final int callingUid = Binder.getCallingUid();
17353 mContext.enforceCallingOrSelfPermission(
17354 android.Manifest.permission.DELETE_PACKAGES, null);
17355 final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
17356 Preconditions.checkNotNull(versionedPackage);
17357 Preconditions.checkNotNull(observer);
17358 Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
17359 PackageManager.VERSION_CODE_HIGHEST,
17360 Long.MAX_VALUE, "versionCode must be >= -1");
17362 final String packageName = versionedPackage.getPackageName();
17363 final long versionCode = versionedPackage.getLongVersionCode();
17364 final String internalPackageName;
17365 synchronized (mLock) {
17366 // Normalize package name to handle renamed packages and static libs
17367 internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
17370 final int uid = Binder.getCallingUid();
17371 if (!isOrphaned(internalPackageName)
17372 && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17373 mHandler.post(() -> {
17375 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17376 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17377 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17378 observer.onUserActionRequired(intent);
17379 } catch (RemoteException re) {
17384 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17385 final int[] users = deleteAllUsers ? mUserManager.getUserIds() : new int[]{userId};
17386 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17387 mContext.enforceCallingOrSelfPermission(
17388 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17389 "deletePackage for user " + userId);
17392 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17393 mHandler.post(() -> {
17395 observer.onPackageDeleted(packageName,
17396 PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17397 } catch (RemoteException re) {
17403 if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17404 mHandler.post(() -> {
17406 observer.onPackageDeleted(packageName,
17407 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17408 } catch (RemoteException re) {
17414 if (DEBUG_REMOVE) {
17415 Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17416 + " deleteAllUsers: " + deleteAllUsers + " version="
17417 + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17418 ? "VERSION_CODE_HIGHEST" : versionCode));
17420 // Queue up an async operation since the package deletion may take a little while.
17421 mHandler.post(() -> {
17423 final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
17424 boolean doDeletePackage = true;
17426 final boolean targetIsInstantApp =
17427 ps.getInstantApp(UserHandle.getUserId(callingUid));
17428 doDeletePackage = !targetIsInstantApp
17429 || canViewInstantApps;
17431 if (doDeletePackage) {
17432 if (!deleteAllUsers) {
17433 returnCode = deletePackageX(internalPackageName, versionCode,
17434 userId, deleteFlags);
17436 int[] blockUninstallUserIds = getBlockUninstallForUsers(
17437 internalPackageName, users);
17438 // If nobody is blocking uninstall, proceed with delete for all users
17439 if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17440 returnCode = deletePackageX(internalPackageName, versionCode,
17441 userId, deleteFlags);
17443 // Otherwise uninstall individually for users with blockUninstalls=false
17444 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17445 for (int userId1 : users) {
17446 if (!ArrayUtils.contains(blockUninstallUserIds, userId1)) {
17447 returnCode = deletePackageX(internalPackageName, versionCode,
17448 userId1, userFlags);
17449 if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17450 Slog.w(TAG, "Package delete failed for user " + userId1
17451 + ", returnCode " + returnCode);
17455 // The app has only been marked uninstalled for certain users.
17456 // We still need to report that delete was blocked
17457 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17461 returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17464 observer.onPackageDeleted(packageName, returnCode, null);
17465 } catch (RemoteException e) {
17466 Log.i(TAG, "Observer no longer exists.");
17471 private String resolveExternalPackageNameLPr(AndroidPackage pkg) {
17472 if (pkg.getStaticSharedLibName() != null) {
17473 return pkg.getManifestPackageName();
17475 return pkg.getPackageName();
17478 @GuardedBy("mLock")
17479 private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
17480 final int callingUid = Binder.getCallingUid();
17481 return resolveInternalPackageNameInternalLocked(packageName, versionCode,
17485 private String resolveInternalPackageNameInternalLocked(
17486 String packageName, long versionCode, int callingUid) {
17487 // Handle renamed packages
17488 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17489 packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17491 // Is this a static library?
17492 LongSparseArray<SharedLibraryInfo> versionedLib =
17493 mStaticLibsByDeclaringPackage.get(packageName);
17494 if (versionedLib == null || versionedLib.size() <= 0) {
17495 return packageName;
17498 // Figure out which lib versions the caller can see
17499 LongSparseLongArray versionsCallerCanSee = null;
17500 final int callingAppId = UserHandle.getAppId(callingUid);
17501 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17502 && callingAppId != Process.ROOT_UID) {
17503 versionsCallerCanSee = new LongSparseLongArray();
17504 String libName = versionedLib.valueAt(0).getName();
17505 String[] uidPackages = getPackagesForUidInternal(callingUid, callingUid);
17506 if (uidPackages != null) {
17507 for (String uidPackage : uidPackages) {
17508 PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17509 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17511 final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
17512 versionsCallerCanSee.append(libVersion, libVersion);
17518 // Caller can see nothing - done
17519 if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17520 return packageName;
17523 // Find the version the caller can see and the app version code
17524 SharedLibraryInfo highestVersion = null;
17525 final int versionCount = versionedLib.size();
17526 for (int i = 0; i < versionCount; i++) {
17527 SharedLibraryInfo libraryInfo = versionedLib.valueAt(i);
17528 if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17529 libraryInfo.getLongVersion()) < 0) {
17532 final long libVersionCode = libraryInfo.getDeclaringPackage().getLongVersionCode();
17533 if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17534 if (libVersionCode == versionCode) {
17535 return libraryInfo.getPackageName();
17537 } else if (highestVersion == null) {
17538 highestVersion = libraryInfo;
17539 } else if (libVersionCode > highestVersion
17540 .getDeclaringPackage().getLongVersionCode()) {
17541 highestVersion = libraryInfo;
17545 if (highestVersion != null) {
17546 return highestVersion.getPackageName();
17549 return packageName;
17552 boolean isCallerVerifier(int callingUid) {
17553 final int callingUserId = UserHandle.getUserId(callingUid);
17554 return mRequiredVerifierPackage != null &&
17555 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
17558 private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17559 if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17560 || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
17563 final int callingUserId = UserHandle.getUserId(callingUid);
17564 // If the caller installed the pkgName, then allow it to silently uninstall.
17565 if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
17569 // Allow package verifier to silently uninstall.
17570 if (mRequiredVerifierPackage != null &&
17571 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
17575 // Allow package uninstaller to silently uninstall.
17576 if (mRequiredUninstallerPackage != null &&
17577 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
17581 // Allow storage manager to silently uninstall.
17582 if (mStorageManagerPackage != null &&
17583 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
17587 // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
17588 // uninstall for device owner provisioning.
17589 if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
17590 == PERMISSION_GRANTED) {
17597 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
17598 int[] result = EMPTY_INT_ARRAY;
17599 for (int userId : userIds) {
17600 if (getBlockUninstallForUser(packageName, userId)) {
17601 result = ArrayUtils.appendInt(result, userId);
17608 public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
17609 final int callingUid = Binder.getCallingUid();
17610 if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
17611 != PERMISSION_GRANTED) {
17612 EventLog.writeEvent(0x534e4554, "128599183", -1, "");
17613 throw new SecurityException(android.Manifest.permission.MANAGE_USERS
17614 + " permission is required to call this API");
17616 if (getInstantAppPackageName(callingUid) != null
17617 && !isCallerSameApp(packageName, callingUid)) {
17620 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
17623 private boolean isPackageDeviceAdmin(String packageName, int userId) {
17624 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
17625 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
17628 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
17629 /* callingUserOnly =*/ false);
17630 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
17631 : deviceOwnerComponentName.getPackageName();
17632 // Does the package contains the device owner?
17633 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise,
17634 // this check is probably not needed, since DO should be registered as a device
17635 // admin on some user too. (Original bug for this: b/17657954)
17636 if (packageName.equals(deviceOwnerPackageName)) {
17639 // Does it contain a device admin for any user?
17641 if (userId == UserHandle.USER_ALL) {
17642 users = mUserManager.getUserIds();
17644 users = new int[]{userId};
17646 for (int i = 0; i < users.length; ++i) {
17647 if (dpm.packageHasActiveAdmins(packageName, users[i])) {
17652 } catch (RemoteException e) {
17657 private boolean shouldKeepUninstalledPackageLPr(String packageName) {
17658 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
17662 * This method is an internal method that could be get invoked either
17663 * to delete an installed package or to clean up a failed installation.
17664 * After deleting an installed package, a broadcast is sent to notify any
17665 * listeners that the package has been removed. For cleaning up a failed
17666 * installation, the broadcast is not necessary since the package's
17667 * installation wouldn't have sent the initial broadcast either
17668 * The key steps in deleting a package are
17669 * deleting the package information in internal structures like mPackages,
17670 * deleting the packages base directories through installd
17671 * updating mSettings to reflect current status
17672 * persisting settings for later use
17673 * sending a broadcast if necessary
17675 int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
17676 final PackageRemovedInfo info = new PackageRemovedInfo(this);
17679 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
17680 ? UserHandle.USER_ALL : userId;
17682 if (isPackageDeviceAdmin(packageName, removeUser)) {
17683 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
17684 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
17687 final PackageSetting uninstalledPs;
17688 final PackageSetting disabledSystemPs;
17689 final AndroidPackage pkg;
17691 // for the uninstall-updates case and restricted profiles, remember the per-
17692 // user handle installed state
17694 /** enabled state of the uninstalled application */
17695 final int origEnabledState;
17696 synchronized (mLock) {
17697 uninstalledPs = mSettings.mPackages.get(packageName);
17698 if (uninstalledPs == null) {
17699 Slog.w(TAG, "Not removing non-existent package " + packageName);
17700 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17703 if (versionCode != PackageManager.VERSION_CODE_HIGHEST
17704 && uninstalledPs.versionCode != versionCode) {
17705 Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
17706 + uninstalledPs.versionCode + " != " + versionCode);
17707 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17710 disabledSystemPs = mSettings.getDisabledSystemPkgLPr(packageName);
17711 // Save the enabled state before we delete the package. When deleting a stub
17712 // application we always set the enabled state to 'disabled'.
17713 origEnabledState = uninstalledPs == null
17714 ? COMPONENT_ENABLED_STATE_DEFAULT : uninstalledPs.getEnabled(userId);
17715 // Static shared libs can be declared by any package, so let us not
17716 // allow removing a package if it provides a lib others depend on.
17717 pkg = mPackages.get(packageName);
17719 allUsers = mUserManager.getUserIds();
17721 if (pkg != null && pkg.getStaticSharedLibName() != null) {
17722 SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(
17723 pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion());
17724 if (libraryInfo != null) {
17725 for (int currUserId : allUsers) {
17726 if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
17729 List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
17730 libraryInfo, MATCH_KNOWN_PACKAGES, currUserId);
17731 if (!ArrayUtils.isEmpty(libClientPackages)) {
17732 Slog.w(TAG, "Not removing package " + pkg.getManifestPackageName()
17733 + " hosting lib " + libraryInfo.getName() + " version "
17734 + libraryInfo.getLongVersion() + " used by " + libClientPackages
17735 + " for user " + currUserId);
17736 return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
17742 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
17745 final int freezeUser;
17746 if (isUpdatedSystemApp(uninstalledPs)
17747 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
17748 // We're downgrading a system app, which will apply to all users, so
17749 // freeze them all during the downgrade
17750 freezeUser = UserHandle.USER_ALL;
17752 freezeUser = removeUser;
17755 synchronized (mInstallLock) {
17756 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
17757 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
17758 deleteFlags, "deletePackageX")) {
17759 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
17760 deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
17762 synchronized (mLock) {
17765 mInstantAppRegistry.onPackageUninstalledLPw(pkg, uninstalledPs,
17766 info.removedUsers);
17768 updateSequenceNumberLP(uninstalledPs, info.removedUsers);
17769 updateInstantAppInstallerLocked(packageName);
17775 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
17776 info.sendPackageRemovedBroadcasts(killApp);
17777 info.sendSystemPackageUpdatedBroadcasts();
17778 info.sendSystemPackageAppearedBroadcasts();
17780 // Force a gc here.
17781 Runtime.getRuntime().gc();
17782 // Delete the resources here after sending the broadcast to let
17783 // other processes clean up before deleting resources.
17784 synchronized (mInstallLock) {
17785 if (info.args != null) {
17786 info.args.doPostDeleteLI(true);
17788 final AndroidPackage stubPkg =
17789 (disabledSystemPs == null) ? null : disabledSystemPs.pkg;
17790 if (stubPkg != null && stubPkg.isStub()) {
17791 final PackageSetting stubPs;
17792 synchronized (mLock) {
17793 // restore the enabled state of the stub; the state is overwritten when
17794 // the stub is uninstalled
17795 stubPs = mSettings.getPackageLPr(stubPkg.getPackageName());
17796 if (stubPs != null) {
17797 stubPs.setEnabled(origEnabledState, userId, "android");
17800 if (origEnabledState == COMPONENT_ENABLED_STATE_DEFAULT
17801 || origEnabledState == COMPONENT_ENABLED_STATE_ENABLED) {
17802 if (DEBUG_COMPRESSION) {
17803 Slog.i(TAG, "Enabling system stub after removal; pkg: "
17804 + stubPkg.getPackageName());
17806 enableCompressedPackage(stubPkg, stubPs);
17811 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17814 static class PackageRemovedInfo {
17815 final PackageSender packageSender;
17816 String removedPackage;
17817 String installerPackageName;
17819 int removedAppId = -1;
17821 int[] removedUsers = null;
17822 int[] broadcastUsers = null;
17823 int[] instantUserIds = null;
17824 SparseArray<Integer> installReasons;
17825 boolean isRemovedPackageSystemUpdate = false;
17827 boolean dataRemoved;
17828 boolean removedForAllUsers;
17829 boolean isStaticSharedLib;
17830 // Clean up resources deleted packages.
17831 InstallArgs args = null;
17832 ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
17834 PackageRemovedInfo(PackageSender packageSender) {
17835 this.packageSender = packageSender;
17838 void sendPackageRemovedBroadcasts(boolean killApp) {
17839 sendPackageRemovedBroadcastInternal(killApp);
17842 void sendSystemPackageUpdatedBroadcasts() {
17843 if (isRemovedPackageSystemUpdate) {
17844 sendSystemPackageUpdatedBroadcastsInternal();
17848 void sendSystemPackageAppearedBroadcasts() {
17849 final int packageCount = (appearedChildPackages != null)
17850 ? appearedChildPackages.size() : 0;
17851 for (int i = 0; i < packageCount; i++) {
17852 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
17853 packageSender.sendPackageAddedForNewUsers(installedInfo.name,
17854 true /*sendBootCompleted*/, false /*startReceiver*/,
17855 UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers, null);
17859 private void sendSystemPackageUpdatedBroadcastsInternal() {
17860 Bundle extras = new Bundle(2);
17861 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
17862 extras.putBoolean(Intent.EXTRA_REPLACING, true);
17863 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17864 removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
17865 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17866 removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
17867 packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
17868 null, null, 0, removedPackage, null, null, null);
17869 if (installerPackageName != null) {
17870 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17871 removedPackage, extras, 0 /*flags*/,
17872 installerPackageName, null, null, null);
17873 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17874 removedPackage, extras, 0 /*flags*/,
17875 installerPackageName, null, null, null);
17879 private void sendPackageRemovedBroadcastInternal(boolean killApp) {
17880 // Don't send static shared library removal broadcasts as these
17881 // libs are visible only the the apps that depend on them an one
17882 // cannot remove the library if it has a dependency.
17883 if (isStaticSharedLib) {
17886 Bundle extras = new Bundle(2);
17887 final int removedUid = removedAppId >= 0 ? removedAppId : uid;
17888 extras.putInt(Intent.EXTRA_UID, removedUid);
17889 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
17890 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
17891 if (isUpdate || isRemovedPackageSystemUpdate) {
17892 extras.putBoolean(Intent.EXTRA_REPLACING, true);
17894 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
17895 if (removedPackage != null) {
17896 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17897 removedPackage, extras, 0, null /*targetPackage*/, null,
17898 broadcastUsers, instantUserIds);
17899 if (installerPackageName != null) {
17900 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17901 removedPackage, extras, 0 /*flags*/,
17902 installerPackageName, null, broadcastUsers, instantUserIds);
17904 if (dataRemoved && !isRemovedPackageSystemUpdate) {
17905 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
17906 removedPackage, extras,
17907 Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17908 null, null, broadcastUsers, instantUserIds);
17909 packageSender.notifyPackageRemoved(removedPackage, removedUid);
17912 if (removedAppId >= 0) {
17913 // If a system app's updates are uninstalled the UID is not actually removed. Some
17914 // services need to know the package name affected.
17915 if (extras.getBoolean(Intent.EXTRA_REPLACING, false)) {
17916 extras.putString(Intent.EXTRA_PACKAGE_NAME, removedPackage);
17919 packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
17920 null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17921 null, null, broadcastUsers, instantUserIds);
17925 void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
17926 removedUsers = userIds;
17927 if (removedUsers == null) {
17928 broadcastUsers = null;
17932 broadcastUsers = EMPTY_INT_ARRAY;
17933 instantUserIds = EMPTY_INT_ARRAY;
17934 for (int i = userIds.length - 1; i >= 0; --i) {
17935 final int userId = userIds[i];
17936 if (deletedPackageSetting.getInstantApp(userId)) {
17937 instantUserIds = ArrayUtils.appendInt(instantUserIds, userId);
17939 broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
17946 * This method deletes the package from internal data structures. If the DELETE_KEEP_DATA
17947 * flag is not set, the data directory is removed as well.
17948 * make sure this flag is set for partially installed apps. If not its meaningless to
17949 * delete a partially installed application.
17951 private void removePackageDataLIF(final PackageSetting deletedPs, int[] allUserHandles,
17952 PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
17953 String packageName = deletedPs.name;
17954 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + deletedPs);
17955 // Retrieve object to delete permissions for shared user later on
17956 final AndroidPackage deletedPkg = deletedPs.pkg;
17957 if (outInfo != null) {
17958 outInfo.removedPackage = packageName;
17959 outInfo.installerPackageName = deletedPs.installSource.installerPackageName;
17960 outInfo.isStaticSharedLib = deletedPkg != null
17961 && deletedPkg.getStaticSharedLibName() != null;
17962 outInfo.populateUsers(deletedPs == null ? null
17963 : deletedPs.queryInstalledUsers(mUserManager.getUserIds(), true), deletedPs);
17966 removePackageLI(deletedPs.name, (flags & PackageManager.DELETE_CHATTY) != 0);
17968 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
17969 final AndroidPackage resolvedPkg;
17970 if (deletedPkg != null) {
17971 resolvedPkg = deletedPkg;
17973 // We don't have a parsed package when it lives on an ejected
17974 // adopted storage device, so fake something together
17975 resolvedPkg = PackageImpl.buildFakeForDeletion(deletedPs.name,
17976 deletedPs.volumeUuid);
17978 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
17979 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
17980 destroyAppProfilesLIF(resolvedPkg);
17981 if (outInfo != null) {
17982 outInfo.dataRemoved = true;
17986 int removedAppId = -1;
17989 boolean installedStateChanged = false;
17990 if (deletedPs != null) {
17991 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
17992 final SparseBooleanArray changedUsers = new SparseBooleanArray();
17993 synchronized (mLock) {
17994 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
17995 clearDefaultBrowserIfNeeded(packageName);
17996 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
17997 removedAppId = mSettings.removePackageLPw(packageName);
17998 if (outInfo != null) {
17999 outInfo.removedAppId = removedAppId;
18001 mPermissionManager.updatePermissions(deletedPs.name, null);
18002 if (deletedPs.sharedUser != null) {
18003 // Remove permissions associated with package. Since runtime
18004 // permissions are per user we have to kill the removed package
18005 // or packages running under the shared user of the removed
18006 // package if revoking the permissions requested only by the removed
18007 // package is successful and this causes a change in gids.
18008 boolean shouldKill = false;
18009 for (int userId : UserManagerService.getInstance().getUserIds()) {
18010 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
18012 shouldKill |= userIdToKill == UserHandle.USER_ALL
18013 || userIdToKill >= UserHandle.USER_SYSTEM;
18015 // If gids changed, kill all affected packages.
18017 mHandler.post(() -> {
18018 // This has to happen with no lock held.
18019 killApplication(deletedPs.name, deletedPs.appId,
18020 KILL_APP_REASON_GIDS_CHANGED);
18024 clearPackagePreferredActivitiesLPw(
18025 deletedPs.name, changedUsers, UserHandle.USER_ALL);
18027 if (changedUsers.size() > 0) {
18028 updateDefaultHomeNotLocked(changedUsers);
18029 postPreferredActivityChangedBroadcast(UserHandle.USER_ALL);
18032 // make sure to preserve per-user disabled state if this removal was just
18033 // a downgrade of a system app to the factory package
18034 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18035 if (DEBUG_REMOVE) {
18036 Slog.d(TAG, "Propagating install state across downgrade");
18038 for (int userId : allUserHandles) {
18039 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18040 if (DEBUG_REMOVE) {
18041 Slog.d(TAG, " user " + userId + " => " + installed);
18043 if (installed != deletedPs.getInstalled(userId)) {
18044 installedStateChanged = true;
18046 deletedPs.setInstalled(installed, userId);
18050 synchronized (mLock) {
18051 // can downgrade to reader
18052 if (writeSettings) {
18053 // Save settings now
18054 mSettings.writeLPr();
18056 if (installedStateChanged) {
18057 mSettings.writeKernelMappingLPr(deletedPs);
18060 if (removedAppId != -1) {
18061 // A user ID was deleted here. Go through all users and remove it
18063 removeKeystoreDataIfNeeded(
18064 mInjector.getUserManagerInternal(), UserHandle.USER_ALL, removedAppId);
18068 private static @Nullable ScanPartition resolveApexToScanPartition(
18069 ApexManager.ActiveApexInfo apexInfo) {
18070 for (int i = 0, size = SYSTEM_PARTITIONS.size(); i < size; i++) {
18071 ScanPartition sp = SYSTEM_PARTITIONS.get(i);
18072 if (apexInfo.preInstalledApexPath.getAbsolutePath().startsWith(
18073 sp.folder.getAbsolutePath())) {
18074 return new ScanPartition(apexInfo.apexDirectory, sp, SCAN_AS_APK_IN_APEX);
18081 * Tries to delete system package.
18083 private void deleteSystemPackageLIF(DeletePackageAction action, PackageSetting deletedPs,
18084 int[] allUserHandles, int flags, @Nullable PackageRemovedInfo outInfo,
18085 boolean writeSettings)
18086 throws SystemDeleteException {
18087 final boolean applyUserRestrictions =
18088 (allUserHandles != null) && outInfo != null && (outInfo.origUsers != null);
18089 final AndroidPackage deletedPkg = deletedPs.pkg;
18090 // Confirm if the system package has been updated
18091 // An updated system app can be deleted. This will also have to restore
18092 // the system pkg from system partition
18094 final PackageSetting disabledPs = action.disabledPs;
18095 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.getPackageName()
18096 + " disabledPs=" + disabledPs);
18097 Slog.d(TAG, "Deleting system pkg from data partition");
18099 if (DEBUG_REMOVE) {
18100 if (applyUserRestrictions) {
18101 Slog.d(TAG, "Remembering install states:");
18102 for (int userId : allUserHandles) {
18103 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
18104 Slog.d(TAG, " u=" + userId + " inst=" + finstalled);
18109 if (outInfo != null) {
18110 // Delete the updated package
18111 outInfo.isRemovedPackageSystemUpdate = true;
18114 if (disabledPs.versionCode < deletedPs.versionCode) {
18115 // Delete data for downgrades
18116 flags &= ~PackageManager.DELETE_KEEP_DATA;
18118 // Preserve data by setting flag
18119 flags |= PackageManager.DELETE_KEEP_DATA;
18122 deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
18123 outInfo, writeSettings);
18126 synchronized (mLock) {
18127 // NOTE: The system package always needs to be enabled; even if it's for
18128 // a compressed stub. If we don't, installing the system package fails
18129 // during scan [scanning checks the disabled packages]. We will reverse
18130 // this later, after we've "installed" the stub.
18131 // Reinstate the old system package
18132 enableSystemPackageLPw(disabledPs.pkg);
18133 // Remove any native libraries from the upgraded package.
18134 removeNativeBinariesLI(deletedPs);
18137 // Install the system package
18138 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18140 installPackageFromSystemLIF(disabledPs.codePathString, allUserHandles,
18141 outInfo == null ? null : outInfo.origUsers, deletedPs.getPermissionsState(),
18143 } catch (PackageManagerException e) {
18144 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.getPackageName() + ": "
18146 // TODO(patb): can we avoid this; throw would come from scan...
18147 throw new SystemDeleteException(e);
18149 if (disabledPs.pkg.isStub()) {
18150 // We've re-installed the stub; make sure it's disabled here. If package was
18151 // originally enabled, we'll install the compressed version of the application
18152 // and re-enable it afterward.
18153 final PackageSetting stubPs = mSettings.mPackages.get(deletedPkg.getPackageName());
18154 if (stubPs != null) {
18156 COMPONENT_ENABLED_STATE_DISABLED, UserHandle.USER_SYSTEM, "android");
18163 * Installs a package that's already on the system partition.
18165 private AndroidPackage installPackageFromSystemLIF(@NonNull String codePathString,
18166 @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
18167 @Nullable PermissionsState origPermissionState, boolean writeSettings)
18168 throws PackageManagerException {
18169 @ParseFlags int parseFlags =
18171 | PackageParser.PARSE_MUST_BE_APK
18172 | PackageParser.PARSE_IS_SYSTEM_DIR;
18173 @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
18174 for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
18175 ScanPartition partition = mDirsToScanAsSystem.get(i);
18176 if (partition.containsPath(codePathString)) {
18177 scanFlags |= partition.scanFlag;
18178 if (partition.containsPrivPath(codePathString)) {
18179 scanFlags |= SCAN_AS_PRIVILEGED;
18185 final File codePath = new File(codePathString);
18186 final AndroidPackage pkg =
18187 scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
18189 PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.getPackageName());
18192 // update shared libraries for the newly re-installed system package
18193 updateSharedLibrariesLocked(pkg, pkgSetting, null, null,
18194 Collections.unmodifiableMap(mPackages));
18195 } catch (PackageManagerException e) {
18196 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18199 prepareAppDataAfterInstallLIF(pkg);
18202 synchronized (mLock) {
18203 PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
18205 // Propagate the permissions state as we do not want to drop on the floor
18206 // runtime permissions. The update permissions method below will take
18207 // care of removing obsolete permissions and grant install permissions.
18208 if (origPermissionState != null) {
18209 ps.getPermissionsState().copyFrom(origPermissionState);
18211 mPermissionManager.updatePermissions(pkg.getPackageName(), pkg);
18213 final boolean applyUserRestrictions
18214 = (allUserHandles != null) && (origUserHandles != null);
18215 if (applyUserRestrictions) {
18216 boolean installedStateChanged = false;
18217 if (DEBUG_REMOVE) {
18218 Slog.d(TAG, "Propagating install state across reinstall");
18220 for (int userId : allUserHandles) {
18221 final boolean installed = ArrayUtils.contains(origUserHandles, userId);
18222 if (DEBUG_REMOVE) {
18223 Slog.d(TAG, " user " + userId + " => " + installed);
18225 if (installed != ps.getInstalled(userId)) {
18226 installedStateChanged = true;
18228 ps.setInstalled(installed, userId);
18230 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
18232 // Regardless of writeSettings we need to ensure that this restriction
18233 // state propagation is persisted
18234 mSettings.writeAllUsersPackageRestrictionsLPr();
18235 if (installedStateChanged) {
18236 mSettings.writeKernelMappingLPr(ps);
18239 // can downgrade to reader here
18240 if (writeSettings) {
18241 mSettings.writeLPr();
18247 private void deleteInstalledPackageLIF(PackageSetting ps,
18248 boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18249 PackageRemovedInfo outInfo, boolean writeSettings) {
18250 synchronized (mLock) {
18251 if (outInfo != null) {
18252 outInfo.uid = ps.appId;
18256 // Delete package data from internal structures and also remove data if flag is set
18257 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18259 // Delete application code and resources only for parent packages
18260 if (deleteCodeAndResources && (outInfo != null)) {
18261 outInfo.args = createInstallArgsForExisting(
18262 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(
18263 ps.primaryCpuAbiString, ps.secondaryCpuAbiString));
18264 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18269 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18271 mContext.enforceCallingOrSelfPermission(
18272 android.Manifest.permission.DELETE_PACKAGES, null);
18273 synchronized (mLock) {
18274 // Cannot block uninstall of static shared libs as they are
18275 // considered a part of the using app (emulating static linking).
18276 // Also static libs are installed always on internal storage.
18277 AndroidPackage pkg = mPackages.get(packageName);
18278 if (pkg != null && pkg.getStaticSharedLibName() != null) {
18279 Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18280 + " providing static shared library: " + pkg.getStaticSharedLibName());
18283 mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
18284 mSettings.writePackageRestrictionsLPr(userId);
18290 public boolean getBlockUninstallForUser(String packageName, int userId) {
18291 synchronized (mLock) {
18292 final PackageSetting ps = mSettings.mPackages.get(packageName);
18293 if (ps == null || shouldFilterApplicationLocked(ps, Binder.getCallingUid(), userId)) {
18296 return mSettings.getBlockUninstallLPr(userId, packageName);
18301 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18302 enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
18303 synchronized (mLock) {
18304 PackageSetting ps = mSettings.mPackages.get(packageName);
18306 Log.w(TAG, "Package doesn't exist: " + packageName);
18309 if (systemUserApp) {
18310 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18312 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18314 mSettings.writeLPr();
18319 private static class DeletePackageAction {
18320 public final PackageSetting deletingPs;
18321 public final PackageSetting disabledPs;
18322 public final PackageRemovedInfo outInfo;
18323 public final int flags;
18324 public final UserHandle user;
18326 private DeletePackageAction(PackageSetting deletingPs, PackageSetting disabledPs,
18327 PackageRemovedInfo outInfo, int flags, UserHandle user) {
18328 this.deletingPs = deletingPs;
18329 this.disabledPs = disabledPs;
18330 this.outInfo = outInfo;
18331 this.flags = flags;
18337 * @return a {@link DeletePackageAction} if the provided package and related state may be
18338 * deleted, {@code null} otherwise.
18341 @GuardedBy("mLock")
18342 private static DeletePackageAction mayDeletePackageLocked(
18343 PackageRemovedInfo outInfo, PackageSetting ps, @Nullable PackageSetting disabledPs,
18344 int flags, UserHandle user) {
18348 if (isSystemApp(ps)) {
18349 final boolean deleteSystem = (flags & PackageManager.DELETE_SYSTEM_APP) != 0;
18350 final boolean deleteAllUsers =
18351 user == null || user.getIdentifier() == UserHandle.USER_ALL;
18352 if ((!deleteSystem || deleteAllUsers) && disabledPs == null) {
18353 Slog.w(TAG, "Attempt to delete unknown system package " + ps.pkg.getPackageName());
18356 // Confirmed if the system package has been updated
18357 // An updated system app can be deleted. This will also have to restore
18358 // the system pkg from system partition reader
18360 return new DeletePackageAction(ps, disabledPs, outInfo, flags, user);
18364 * This method handles package deletion in general
18366 private boolean deletePackageLIF(@NonNull String packageName, UserHandle user,
18367 boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18368 PackageRemovedInfo outInfo, boolean writeSettings,
18369 ParsedPackage replacingPackage) {
18370 final DeletePackageAction action;
18371 synchronized (mLock) {
18372 final PackageSetting ps = mSettings.mPackages.get(packageName);
18373 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
18374 action = mayDeletePackageLocked(outInfo, ps, disabledPs, flags, user);
18376 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18377 if (null == action) {
18378 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: action was null");
18384 executeDeletePackageLIF(action, packageName, deleteCodeAndResources,
18385 allUserHandles, writeSettings, replacingPackage);
18386 } catch (SystemDeleteException e) {
18387 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: system deletion failure", e);
18393 private static class SystemDeleteException extends Exception {
18394 public final PackageManagerException reason;
18396 private SystemDeleteException(PackageManagerException reason) {
18397 this.reason = reason;
18401 /** Deletes a package. Only throws when install of a disabled package fails. */
18402 private void executeDeletePackageLIF(DeletePackageAction action,
18403 String packageName, boolean deleteCodeAndResources,
18404 int[] allUserHandles, boolean writeSettings,
18405 ParsedPackage replacingPackage) throws SystemDeleteException {
18406 final PackageSetting ps = action.deletingPs;
18407 final PackageRemovedInfo outInfo = action.outInfo;
18408 final UserHandle user = action.user;
18409 final int flags = action.flags;
18410 final boolean systemApp = isSystemApp(ps);
18412 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
18413 if (ps.getPermissionsState().hasPermission(Manifest.permission.SUSPEND_APPS, userId)) {
18414 unsuspendForSuspendingPackage(packageName, userId);
18416 if ((!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)
18417 && userId != UserHandle.USER_ALL) {
18418 // The caller is asking that the package only be deleted for a single
18419 // user. To do this, we just mark its uninstalled state and delete
18420 // its data. If this is a system app, we only allow this to happen if
18421 // they have set the special DELETE_SYSTEM_APP which requests different
18422 // semantics than normal for uninstalling system apps.
18423 final boolean clearPackageStateAndReturn;
18424 synchronized (mLock) {
18425 markPackageUninstalledForUserLPw(ps, user);
18427 // Do not uninstall the APK if an app should be cached
18428 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18429 if (ps.isAnyInstalled(mUserManager.getUserIds()) || keepUninstalledPackage) {
18430 // Other users still have this package installed, so all
18431 // we need to do is clear this user's data and save that
18432 // it is uninstalled.
18433 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18434 clearPackageStateAndReturn = true;
18436 // We need to set it back to 'installed' so the uninstall
18437 // broadcasts will be sent correctly.
18438 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18439 ps.setInstalled(true, userId);
18440 mSettings.writeKernelMappingLPr(ps);
18441 clearPackageStateAndReturn = false;
18444 // This is a system app, so we assume that the
18445 // other users still have this package installed, so all
18446 // we need to do is clear this user's data and save that
18447 // it is uninstalled.
18448 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18449 clearPackageStateAndReturn = true;
18452 if (clearPackageStateAndReturn) {
18453 clearPackageStateForUserLIF(ps, userId, outInfo, flags);
18454 synchronized (mLock) {
18455 scheduleWritePackageRestrictionsLocked(user);
18461 // TODO(b/109941548): break reasons for ret = false out into mayDelete method
18463 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18464 // When an updated system application is deleted we delete the existing resources
18465 // as well and fall back to existing code in system partition
18466 deleteSystemPackageLIF(action, ps, allUserHandles, flags, outInfo, writeSettings);
18468 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18469 deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18470 outInfo, writeSettings);
18473 // Take a note whether we deleted the package for all users
18474 if (outInfo != null) {
18475 outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18479 @GuardedBy("mLock")
18480 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18481 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18482 ? mUserManager.getUserIds() : new int[] {user.getIdentifier()};
18483 for (int nextUserId : userIds) {
18484 if (DEBUG_REMOVE) {
18485 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18487 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18488 false /*installed*/,
18490 true /*notLaunched*/,
18492 0 /*distractionFlags*/,
18493 false /*suspended*/,
18494 null /*suspendParams*/,
18495 false /*instantApp*/,
18496 false /*virtualPreload*/,
18497 null /*lastDisableAppCaller*/,
18498 null /*enabledComponents*/,
18499 null /*disabledComponents*/,
18500 ps.readUserState(nextUserId).domainVerificationStatus,
18501 0, PackageManager.INSTALL_REASON_UNKNOWN,
18502 null /*harmfulAppWarning*/);
18504 mSettings.writeKernelMappingLPr(ps);
18507 private void clearPackageStateForUserLIF(PackageSetting ps, int userId,
18508 PackageRemovedInfo outInfo, int flags) {
18509 final AndroidPackage pkg;
18510 synchronized (mLock) {
18511 pkg = mPackages.get(ps.name);
18514 destroyAppProfilesLIF(pkg);
18516 final int[] userIds = (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds()
18517 : new int[] {userId};
18518 for (int nextUserId : userIds) {
18519 if (DEBUG_REMOVE) {
18520 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18524 destroyAppDataLIF(pkg, nextUserId,
18525 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
18526 clearDefaultBrowserIfNeededForUser(ps.name, nextUserId);
18527 removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), nextUserId, ps.appId);
18528 clearPackagePreferredActivities(ps.name, nextUserId);
18529 mPermissionManager.resetRuntimePermissions(pkg, nextUserId);
18532 if (outInfo != null) {
18533 outInfo.removedPackage = ps.name;
18534 outInfo.installerPackageName = ps.installSource.installerPackageName;
18535 outInfo.isStaticSharedLib = pkg != null && pkg.getStaticSharedLibName() != null;
18536 outInfo.removedAppId = ps.appId;
18537 outInfo.removedUsers = userIds;
18538 outInfo.broadcastUsers = userIds;
18543 public void clearApplicationProfileData(String packageName) {
18544 enforceSystemOrRoot("Only the system can clear all profile data");
18546 final AndroidPackage pkg;
18547 synchronized (mLock) {
18548 pkg = mPackages.get(packageName);
18551 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
18552 synchronized (mInstallLock) {
18553 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
18559 public void clearApplicationUserData(final String packageName,
18560 final IPackageDataObserver observer, final int userId) {
18561 mContext.enforceCallingOrSelfPermission(
18562 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
18564 final int callingUid = Binder.getCallingUid();
18565 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18566 true /* requireFullPermission */, false /* checkShell */, "clear application data");
18568 final PackageSetting ps = mSettings.getPackageLPr(packageName);
18569 final boolean filterApp =
18570 (ps != null && shouldFilterApplicationLocked(ps, callingUid, userId));
18571 if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
18572 throw new SecurityException("Cannot clear data for a protected package: "
18575 // Queue up an async operation since the package deletion may take a little while.
18576 mHandler.post(new Runnable() {
18577 public void run() {
18578 mHandler.removeCallbacks(this);
18579 final boolean succeeded;
18581 try (PackageFreezer freezer = freezePackage(packageName,
18582 "clearApplicationUserData")) {
18583 synchronized (mInstallLock) {
18584 succeeded = clearApplicationUserDataLIF(packageName, userId);
18586 synchronized (mLock) {
18587 mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
18588 packageName, userId);
18592 // invoke DeviceStorageMonitor's update method to clear any notifications
18593 DeviceStorageMonitorInternal dsm = LocalServices
18594 .getService(DeviceStorageMonitorInternal.class);
18598 if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
18599 == PERMISSION_GRANTED) {
18600 unsuspendForSuspendingPackage(packageName, userId);
18601 removeAllDistractingPackageRestrictions(userId);
18602 flushPackageRestrictionsAsUserInternalLocked(userId);
18608 if (observer != null) {
18610 observer.onRemoveCompleted(packageName, succeeded);
18611 } catch (RemoteException e) {
18612 Log.i(TAG, "Observer no longer exists.");
18614 } //end if observer
18619 private boolean clearApplicationUserDataLIF(String packageName, int userId) {
18620 if (packageName == null) {
18621 Slog.w(TAG, "Attempt to delete null packageName.");
18625 // Try finding details about the requested package
18626 AndroidPackage pkg;
18628 synchronized (mLock) {
18629 pkg = mPackages.get(packageName);
18630 ps = mSettings.mPackages.get(packageName);
18638 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18641 mPermissionManager.resetRuntimePermissions(pkg, userId);
18643 clearAppDataLIF(pkg, userId,
18644 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
18646 final int appId = UserHandle.getAppId(pkg.getUid());
18647 removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), userId, appId);
18649 UserManagerInternal umInternal = mInjector.getUserManagerInternal();
18651 if (umInternal.isUserUnlockingOrUnlocked(userId)) {
18652 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18653 } else if (umInternal.isUserRunning(userId)) {
18654 flags = StorageManager.FLAG_STORAGE_DE;
18658 prepareAppDataContentsLIF(pkg, ps, userId, flags);
18663 private void resetNetworkPolicies(int userId) {
18664 mInjector.getNetworkPolicyManagerInternal().resetUserState(userId);
18668 * Remove entries from the keystore daemon. Will only remove it if the
18669 * {@code appId} is valid.
18671 private static void removeKeystoreDataIfNeeded(UserManagerInternal um, @UserIdInt int userId,
18672 @AppIdInt int appId) {
18677 final KeyStore keyStore = KeyStore.getInstance();
18678 if (keyStore != null) {
18679 if (userId == UserHandle.USER_ALL) {
18680 for (final int individual : um.getUserIds()) {
18681 keyStore.clearUid(UserHandle.getUid(individual, appId));
18684 keyStore.clearUid(UserHandle.getUid(userId, appId));
18687 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
18692 public void deleteApplicationCacheFiles(final String packageName,
18693 final IPackageDataObserver observer) {
18694 final int userId = UserHandle.getCallingUserId();
18695 deleteApplicationCacheFilesAsUser(packageName, userId, observer);
18699 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
18700 final IPackageDataObserver observer) {
18701 final int callingUid = Binder.getCallingUid();
18702 if (mContext.checkCallingOrSelfPermission(
18703 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES)
18704 != PackageManager.PERMISSION_GRANTED) {
18705 // If the caller has the old delete cache permission, silently ignore. Else throw.
18706 if (mContext.checkCallingOrSelfPermission(
18707 android.Manifest.permission.DELETE_CACHE_FILES)
18708 == PackageManager.PERMISSION_GRANTED) {
18709 Slog.w(TAG, "Calling uid " + callingUid + " does not have " +
18710 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES +
18711 ", silently ignoring");
18714 mContext.enforceCallingOrSelfPermission(
18715 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
18717 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18718 /* requireFullPermission= */ true, /* checkShell= */ false,
18719 "delete application cache files");
18720 final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
18721 android.Manifest.permission.ACCESS_INSTANT_APPS);
18723 final AndroidPackage pkg;
18724 synchronized (mLock) {
18725 pkg = mPackages.get(packageName);
18728 // Queue up an async operation since the package deletion may take a little while.
18729 mHandler.post(() -> {
18730 final PackageSetting ps = pkg == null ? null : getPackageSetting(pkg.getPackageName());
18731 boolean doClearData = true;
18733 final boolean targetIsInstantApp =
18734 ps.getInstantApp(UserHandle.getUserId(callingUid));
18735 doClearData = !targetIsInstantApp
18736 || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
18739 synchronized (mInstallLock) {
18740 final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL;
18741 // We're only clearing cache files, so we don't care if the
18742 // app is unfrozen and still able to run
18743 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
18744 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18747 if (observer != null) {
18749 observer.onRemoveCompleted(packageName, true);
18750 } catch (RemoteException e) {
18751 Log.i(TAG, "Observer no longer exists.");
18758 public void getPackageSizeInfo(final String packageName, int userId,
18759 final IPackageStatsObserver observer) {
18760 throw new UnsupportedOperationException(
18761 "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
18764 @GuardedBy("mInstallLock")
18765 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
18766 final PackageSetting ps;
18767 synchronized (mLock) {
18768 ps = mSettings.mPackages.get(packageName);
18770 Slog.w(TAG, "Failed to find settings for " + packageName);
18775 final String[] packageNames = { packageName };
18776 final long[] ceDataInodes = { ps.getCeDataInode(userId) };
18777 final String[] codePaths = { ps.codePathString };
18780 mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
18781 ps.appId, ceDataInodes, codePaths, stats);
18783 // For now, ignore code size of packages on system partition
18784 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
18785 stats.codeSize = 0;
18788 // External clients expect these to be tracked separately
18789 stats.dataSize -= stats.cacheSize;
18791 } catch (InstallerException e) {
18792 Slog.w(TAG, String.valueOf(e));
18799 @GuardedBy("mLock")
18800 private int getUidTargetSdkVersionLockedLPr(int uid) {
18801 final int appId = UserHandle.getAppId(uid);
18802 final Object obj = mSettings.getSettingLPr(appId);
18803 if (obj instanceof SharedUserSetting) {
18804 final SharedUserSetting sus = (SharedUserSetting) obj;
18805 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
18806 final Iterator<PackageSetting> it = sus.packages.iterator();
18807 while (it.hasNext()) {
18808 final PackageSetting ps = it.next();
18809 if (ps.pkg != null) {
18810 int v = ps.pkg.getTargetSdkVersion();
18811 if (v < vers) vers = v;
18815 } else if (obj instanceof PackageSetting) {
18816 final PackageSetting ps = (PackageSetting) obj;
18817 if (ps.pkg != null) {
18818 return ps.pkg.getTargetSdkVersion();
18821 return Build.VERSION_CODES.CUR_DEVELOPMENT;
18824 @GuardedBy("mLock")
18825 private int getPackageTargetSdkVersionLockedLPr(String packageName) {
18826 final AndroidPackage p = mPackages.get(packageName);
18828 return p.getTargetSdkVersion();
18830 return Build.VERSION_CODES.CUR_DEVELOPMENT;
18834 public void addPreferredActivity(IntentFilter filter, int match,
18835 ComponentName[] set, ComponentName activity, int userId) {
18836 addPreferredActivityInternal(filter, match, set, activity, true, userId,
18837 "Adding preferred");
18840 private void addPreferredActivityInternal(IntentFilter filter, int match,
18841 ComponentName[] set, ComponentName activity, boolean always, int userId,
18844 int callingUid = Binder.getCallingUid();
18845 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18846 true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
18847 if (mContext.checkCallingOrSelfPermission(
18848 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18849 != PackageManager.PERMISSION_GRANTED) {
18850 if (getUidTargetSdkVersionLockedLPr(callingUid)
18851 < Build.VERSION_CODES.FROYO) {
18852 Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
18856 mContext.enforceCallingOrSelfPermission(
18857 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18859 if (filter.countActions() == 0) {
18860 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
18863 if (DEBUG_PREFERRED) {
18864 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
18866 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
18868 synchronized (mLock) {
18869 final PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
18870 pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
18871 scheduleWritePackageRestrictionsLocked(userId);
18873 if (!updateDefaultHomeNotLocked(userId)) {
18874 postPreferredActivityChangedBroadcast(userId);
18878 private void postPreferredActivityChangedBroadcast(int userId) {
18879 mHandler.post(() -> {
18880 final IActivityManager am = ActivityManager.getService();
18885 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
18886 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18887 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
18889 am.broadcastIntentWithFeature(null, null, intent, null, null,
18890 0, null, null, null, android.app.AppOpsManager.OP_NONE,
18891 null, false, false, userId);
18892 } catch (RemoteException e) {
18898 public void replacePreferredActivity(IntentFilter filter, int match,
18899 ComponentName[] set, ComponentName activity, int userId) {
18900 if (filter.countActions() != 1) {
18901 throw new IllegalArgumentException(
18902 "replacePreferredActivity expects filter to have only 1 action.");
18904 if (filter.countDataAuthorities() != 0
18905 || filter.countDataPaths() != 0
18906 || filter.countDataSchemes() > 1
18907 || filter.countDataTypes() != 0) {
18908 throw new IllegalArgumentException(
18909 "replacePreferredActivity expects filter to have no data authorities, " +
18910 "paths, or types; and at most one scheme.");
18913 final int callingUid = Binder.getCallingUid();
18914 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18915 true /* requireFullPermission */, false /* checkShell */,
18916 "replace preferred activity");
18917 if (mContext.checkCallingOrSelfPermission(
18918 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18919 != PackageManager.PERMISSION_GRANTED) {
18920 synchronized (mLock) {
18921 if (getUidTargetSdkVersionLockedLPr(callingUid)
18922 < Build.VERSION_CODES.FROYO) {
18923 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
18924 + Binder.getCallingUid());
18928 mContext.enforceCallingOrSelfPermission(
18929 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18932 synchronized (mLock) {
18933 final PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
18935 // Get all of the existing entries that exactly match this filter.
18936 final ArrayList<PreferredActivity> existing = pir.findFilters(filter);
18937 if (existing != null && existing.size() == 1) {
18938 final PreferredActivity cur = existing.get(0);
18939 if (DEBUG_PREFERRED) {
18940 Slog.i(TAG, "Checking replace of preferred:");
18941 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
18942 if (!cur.mPref.mAlways) {
18943 Slog.i(TAG, " -- CUR; not mAlways!");
18945 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch);
18946 Slog.i(TAG, " -- CUR: mSet="
18947 + Arrays.toString(cur.mPref.mSetComponents));
18948 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent);
18949 Slog.i(TAG, " -- NEW: mMatch="
18950 + (match&IntentFilter.MATCH_CATEGORY_MASK));
18951 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set));
18952 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString());
18955 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
18956 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
18957 && cur.mPref.sameSet(set)) {
18958 // Setting the preferred activity to what it happens to be already
18959 if (DEBUG_PREFERRED) {
18960 Slog.i(TAG, "Replacing with same preferred activity "
18961 + cur.mPref.mShortComponent + " for user "
18963 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
18968 if (existing != null) {
18969 if (DEBUG_PREFERRED) {
18970 Slog.i(TAG, existing.size() + " existing preferred matches for:");
18971 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
18973 for (int i = existing.size() - 1; i >= 0; --i) {
18974 final PreferredActivity pa = existing.get(i);
18975 if (DEBUG_PREFERRED) {
18976 Slog.i(TAG, "Removing existing preferred activity "
18977 + pa.mPref.mComponent + ":");
18978 pa.dump(new LogPrinter(Log.INFO, TAG), " ");
18980 pir.removeFilter(pa);
18985 addPreferredActivityInternal(filter, match, set, activity, true, userId,
18986 "Replacing preferred");
18990 public void clearPackagePreferredActivities(String packageName) {
18991 final int callingUid = Binder.getCallingUid();
18992 if (getInstantAppPackageName(callingUid) != null) {
18996 synchronized (mLock) {
18997 AndroidPackage pkg = mPackages.get(packageName);
18998 if (pkg == null || !isCallerSameApp(packageName, callingUid)) {
18999 if (mContext.checkCallingOrSelfPermission(
19000 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19001 != PackageManager.PERMISSION_GRANTED) {
19002 if (getUidTargetSdkVersionLockedLPr(callingUid)
19003 < Build.VERSION_CODES.FROYO) {
19004 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
19008 mContext.enforceCallingOrSelfPermission(
19009 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19012 final PackageSetting ps = mSettings.getPackageLPr(packageName);
19014 && shouldFilterApplicationLocked(
19015 ps, callingUid, UserHandle.getUserId(callingUid))) {
19019 int callingUserId = UserHandle.getCallingUserId();
19020 clearPackagePreferredActivities(packageName, callingUserId);
19023 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19024 private void clearPackagePreferredActivities(String packageName, int userId) {
19025 final SparseBooleanArray changedUsers = new SparseBooleanArray();
19027 clearPackagePreferredActivitiesLPw(packageName, changedUsers, userId);
19028 if (changedUsers.size() > 0) {
19029 updateDefaultHomeNotLocked(changedUsers);
19030 postPreferredActivityChangedBroadcast(userId);
19031 synchronized (mLock) {
19032 scheduleWritePackageRestrictionsLocked(userId);
19037 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19038 @GuardedBy("mLock")
19039 private void clearPackagePreferredActivitiesLPw(String packageName,
19040 @NonNull SparseBooleanArray outUserChanged, int userId) {
19041 ArrayList<PreferredActivity> removed = null;
19042 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19043 final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19044 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19045 if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19048 Iterator<PreferredActivity> it = pir.filterIterator();
19049 while (it.hasNext()) {
19050 PreferredActivity pa = it.next();
19051 // Mark entry for removal only if it matches the package name
19052 // and the entry is of type "always".
19053 if (packageName == null ||
19054 (pa.mPref.mComponent.getPackageName().equals(packageName)
19055 && pa.mPref.mAlways)) {
19056 if (removed == null) {
19057 removed = new ArrayList<>();
19062 if (removed != null) {
19063 for (int j=0; j<removed.size(); j++) {
19064 PreferredActivity pa = removed.get(j);
19065 pir.removeFilter(pa);
19067 outUserChanged.put(thisUserId, true);
19072 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19073 @GuardedBy("mLock")
19074 private void clearIntentFilterVerificationsLPw(int userId) {
19075 final int packageCount = mPackages.size();
19076 for (int i = 0; i < packageCount; i++) {
19077 AndroidPackage pkg = mPackages.valueAt(i);
19078 clearIntentFilterVerificationsLPw(pkg.getPackageName(), userId);
19082 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19083 @GuardedBy("mLock")
19084 void clearIntentFilterVerificationsLPw(String packageName, int userId) {
19085 if (userId == UserHandle.USER_ALL) {
19086 if (mSettings.removeIntentFilterVerificationLPw(packageName,
19087 mUserManager.getUserIds())) {
19088 for (int oneUserId : mUserManager.getUserIds()) {
19089 scheduleWritePackageRestrictionsLocked(oneUserId);
19093 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
19094 scheduleWritePackageRestrictionsLocked(userId);
19099 /** Clears state for all users, and touches intent filter verification policy */
19100 void clearDefaultBrowserIfNeeded(String packageName) {
19101 for (int oneUserId : mUserManager.getUserIds()) {
19102 clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
19106 private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
19107 final String defaultBrowserPackageName = mPermissionManager.getDefaultBrowser(userId);
19108 if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
19109 if (packageName.equals(defaultBrowserPackageName)) {
19110 mPermissionManager.setDefaultBrowser(null, true, true, userId);
19116 public void resetApplicationPreferences(int userId) {
19117 mContext.enforceCallingOrSelfPermission(
19118 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19119 final long identity = Binder.clearCallingIdentity();
19122 final SparseBooleanArray changedUsers = new SparseBooleanArray();
19123 clearPackagePreferredActivitiesLPw(null, changedUsers, userId);
19124 if (changedUsers.size() > 0) {
19125 postPreferredActivityChangedBroadcast(userId);
19127 synchronized (mLock) {
19128 mSettings.applyDefaultPreferredAppsLPw(userId);
19129 clearIntentFilterVerificationsLPw(userId);
19130 primeDomainVerificationsLPw(userId);
19132 mPermissionManager.resetAllRuntimePermissions(userId);
19133 updateDefaultHomeNotLocked(userId);
19134 // TODO: We have to reset the default SMS and Phone. This requires
19135 // significant refactoring to keep all default apps in the package
19136 // manager (cleaner but more work) or have the services provide
19137 // callbacks to the package manager to request a default app reset.
19138 mPermissionManager.setDefaultBrowser(null, true, true, userId);
19139 resetNetworkPolicies(userId);
19140 synchronized (mLock) {
19141 scheduleWritePackageRestrictionsLocked(userId);
19144 Binder.restoreCallingIdentity(identity);
19149 public int getPreferredActivities(List<IntentFilter> outFilters,
19150 List<ComponentName> outActivities, String packageName) {
19151 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19155 final int userId = UserHandle.getCallingUserId();
19157 synchronized (mLock) {
19158 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19160 final Iterator<PreferredActivity> it = pir.filterIterator();
19161 while (it.hasNext()) {
19162 final PreferredActivity pa = it.next();
19163 if (packageName == null
19164 || (pa.mPref.mComponent.getPackageName().equals(packageName)
19165 && pa.mPref.mAlways)) {
19166 if (outFilters != null) {
19167 outFilters.add(new IntentFilter(pa));
19169 if (outActivities != null) {
19170 outActivities.add(pa.mPref.mComponent);
19181 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19183 int callingUid = Binder.getCallingUid();
19184 if (callingUid != Process.SYSTEM_UID) {
19185 throw new SecurityException(
19186 "addPersistentPreferredActivity can only be run by the system");
19188 if (filter.countActions() == 0) {
19189 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19192 if (DEBUG_PREFERRED) {
19193 Slog.i(TAG, "Adding persistent preferred activity " + activity
19194 + " for user " + userId + ":");
19195 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
19197 synchronized (mLock) {
19198 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19199 new PersistentPreferredActivity(filter, activity));
19200 scheduleWritePackageRestrictionsLocked(userId);
19202 updateDefaultHomeNotLocked(userId);
19203 postPreferredActivityChangedBroadcast(userId);
19207 public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19208 int callingUid = Binder.getCallingUid();
19209 if (callingUid != Process.SYSTEM_UID) {
19210 throw new SecurityException(
19211 "clearPackagePersistentPreferredActivities can only be run by the system");
19213 ArrayList<PersistentPreferredActivity> removed = null;
19214 boolean changed = false;
19215 synchronized (mLock) {
19216 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19217 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19218 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19220 if (userId != thisUserId) {
19223 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19224 while (it.hasNext()) {
19225 PersistentPreferredActivity ppa = it.next();
19226 // Mark entry for removal only if it matches the package name.
19227 if (ppa.mComponent.getPackageName().equals(packageName)) {
19228 if (removed == null) {
19229 removed = new ArrayList<>();
19234 if (removed != null) {
19235 for (int j=0; j<removed.size(); j++) {
19236 PersistentPreferredActivity ppa = removed.get(j);
19237 ppir.removeFilter(ppa);
19244 updateDefaultHomeNotLocked(userId);
19245 postPreferredActivityChangedBroadcast(userId);
19246 synchronized (mLock) {
19247 scheduleWritePackageRestrictionsLocked(userId);
19253 * Common machinery for picking apart a restored XML blob and passing
19254 * it to a caller-supplied functor to be applied to the running system.
19256 private void restoreFromXml(XmlPullParser parser, int userId,
19257 String expectedStartTag, BlobXmlRestorer functor)
19258 throws IOException, XmlPullParserException {
19260 while ((type = parser.next()) != XmlPullParser.START_TAG
19261 && type != XmlPullParser.END_DOCUMENT) {
19263 if (type != XmlPullParser.START_TAG) {
19264 // oops didn't find a start tag?!
19265 if (DEBUG_BACKUP) {
19266 Slog.e(TAG, "Didn't find start tag during restore");
19270 // this is supposed to be TAG_PREFERRED_BACKUP
19271 if (!expectedStartTag.equals(parser.getName())) {
19272 if (DEBUG_BACKUP) {
19273 Slog.e(TAG, "Found unexpected tag " + parser.getName());
19278 // skip interfering stuff, then we're aligned with the backing implementation
19279 while ((type = parser.next()) == XmlPullParser.TEXT) { }
19280 functor.apply(parser, userId);
19283 private interface BlobXmlRestorer {
19284 void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19288 * Non-Binder method, support for the backup/restore mechanism: write the
19289 * full set of preferred activities in its canonical XML format. Returns the
19290 * XML output as a byte array, or null if there is none.
19293 public byte[] getPreferredActivityBackup(int userId) {
19294 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19295 throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19298 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19300 final XmlSerializer serializer = new FastXmlSerializer();
19301 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19302 serializer.startDocument(null, true);
19303 serializer.startTag(null, TAG_PREFERRED_BACKUP);
19305 synchronized (mLock) {
19306 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19309 serializer.endTag(null, TAG_PREFERRED_BACKUP);
19310 serializer.endDocument();
19311 serializer.flush();
19312 } catch (Exception e) {
19313 if (DEBUG_BACKUP) {
19314 Slog.e(TAG, "Unable to write preferred activities for backup", e);
19319 return dataStream.toByteArray();
19323 public void restorePreferredActivities(byte[] backup, int userId) {
19324 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19325 throw new SecurityException("Only the system may call restorePreferredActivities()");
19329 final XmlPullParser parser = Xml.newPullParser();
19330 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19331 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19332 (readParser, readUserId) -> {
19333 synchronized (mLock) {
19334 mSettings.readPreferredActivitiesLPw(readParser, readUserId);
19336 updateDefaultHomeNotLocked(readUserId);
19338 } catch (Exception e) {
19339 if (DEBUG_BACKUP) {
19340 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19346 * Non-Binder method, support for the backup/restore mechanism: write the
19347 * default browser (etc) settings in its canonical XML format. Returns the default
19348 * browser XML representation as a byte array, or null if there is none.
19351 public byte[] getDefaultAppsBackup(int userId) {
19352 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19353 throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19356 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19358 final XmlSerializer serializer = new FastXmlSerializer();
19359 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19360 serializer.startDocument(null, true);
19361 serializer.startTag(null, TAG_DEFAULT_APPS);
19363 synchronized (mLock) {
19364 mSettings.writeDefaultAppsLPr(serializer, userId);
19367 serializer.endTag(null, TAG_DEFAULT_APPS);
19368 serializer.endDocument();
19369 serializer.flush();
19370 } catch (Exception e) {
19371 if (DEBUG_BACKUP) {
19372 Slog.e(TAG, "Unable to write default apps for backup", e);
19377 return dataStream.toByteArray();
19381 public void restoreDefaultApps(byte[] backup, int userId) {
19382 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19383 throw new SecurityException("Only the system may call restoreDefaultApps()");
19387 final XmlPullParser parser = Xml.newPullParser();
19388 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19389 restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19390 (parser1, userId1) -> {
19391 final String defaultBrowser;
19392 synchronized (mLock) {
19393 mSettings.readDefaultAppsLPw(parser1, userId1);
19394 defaultBrowser = mSettings.removeDefaultBrowserPackageNameLPw(userId1);
19396 if (defaultBrowser != null) {
19398 .setDefaultBrowser(defaultBrowser, false, false, userId1);
19401 } catch (Exception e) {
19402 if (DEBUG_BACKUP) {
19403 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19409 public byte[] getIntentFilterVerificationBackup(int userId) {
19410 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19411 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19414 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19416 final XmlSerializer serializer = new FastXmlSerializer();
19417 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19418 serializer.startDocument(null, true);
19419 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19421 synchronized (mLock) {
19422 mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19425 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19426 serializer.endDocument();
19427 serializer.flush();
19428 } catch (Exception e) {
19429 if (DEBUG_BACKUP) {
19430 Slog.e(TAG, "Unable to write default apps for backup", e);
19435 return dataStream.toByteArray();
19439 public void restoreIntentFilterVerification(byte[] backup, int userId) {
19440 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19441 throw new SecurityException("Only the system may call restorePreferredActivities()");
19445 final XmlPullParser parser = Xml.newPullParser();
19446 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19447 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19448 (parser1, userId1) -> {
19449 synchronized (mLock) {
19450 mSettings.readAllDomainVerificationsLPr(parser1, userId1);
19451 mSettings.writeLPr();
19454 } catch (Exception e) {
19455 if (DEBUG_BACKUP) {
19456 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19462 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
19463 int sourceUserId, int targetUserId, int flags) {
19464 mContext.enforceCallingOrSelfPermission(
19465 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19466 int callingUid = Binder.getCallingUid();
19467 enforceOwnerRights(ownerPackage, callingUid);
19468 PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
19469 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19470 if (intentFilter.countActions() == 0) {
19471 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
19474 synchronized (mLock) {
19475 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
19476 ownerPackage, targetUserId, flags);
19477 CrossProfileIntentResolver resolver =
19478 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19479 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
19480 // We have all those whose filter is equal. Now checking if the rest is equal as well.
19481 if (existing != null) {
19482 int size = existing.size();
19483 for (int i = 0; i < size; i++) {
19484 if (newFilter.equalsIgnoreFilter(existing.get(i))) {
19489 resolver.addFilter(newFilter);
19490 scheduleWritePackageRestrictionsLocked(sourceUserId);
19495 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
19496 mContext.enforceCallingOrSelfPermission(
19497 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19498 final int callingUid = Binder.getCallingUid();
19499 enforceOwnerRights(ownerPackage, callingUid);
19500 PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
19501 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19502 synchronized (mLock) {
19503 CrossProfileIntentResolver resolver =
19504 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19505 ArraySet<CrossProfileIntentFilter> set =
19506 new ArraySet<>(resolver.filterSet());
19507 for (CrossProfileIntentFilter filter : set) {
19508 if (filter.getOwnerPackage().equals(ownerPackage)) {
19509 resolver.removeFilter(filter);
19512 scheduleWritePackageRestrictionsLocked(sourceUserId);
19516 // Enforcing that callingUid is owning pkg on userId
19517 private void enforceOwnerRights(String pkg, int callingUid) {
19518 // The system owns everything.
19519 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19522 final int callingUserId = UserHandle.getUserId(callingUid);
19523 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
19525 throw new IllegalArgumentException("Unknown package " + pkg + " on user "
19528 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
19529 throw new SecurityException("Calling uid " + callingUid
19530 + " does not own package " + pkg);
19535 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
19536 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19539 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
19543 * Send a {@code PackageInstaller.ACTION_SESSION_UPDATED} broadcast intent, containing
19544 * the {@code sessionInfo} in the extra field {@code PackageInstaller.EXTRA_SESSION}.
19546 public void sendSessionUpdatedBroadcast(PackageInstaller.SessionInfo sessionInfo,
19548 if (TextUtils.isEmpty(sessionInfo.installerPackageName)) {
19551 Intent sessionUpdatedIntent = new Intent(PackageInstaller.ACTION_SESSION_UPDATED)
19552 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
19553 .setPackage(sessionInfo.installerPackageName);
19554 mContext.sendBroadcastAsUser(sessionUpdatedIntent, UserHandle.of(userId));
19557 public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
19558 UserManagerService ums = UserManagerService.getInstance();
19559 if (ums != null && !sessionInfo.isStaged()) {
19560 final UserInfo parent = ums.getProfileParent(userId);
19561 final int launcherUid = (parent != null) ? parent.id : userId;
19562 final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
19563 if (launcherComponent != null) {
19564 Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
19565 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
19566 .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
19567 .setPackage(launcherComponent.getPackageName());
19568 mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
19570 // TODO(b/122900055) Change/Remove this and replace with new permission role.
19571 if (mAppPredictionServicePackage != null) {
19572 Intent predictorIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
19573 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
19574 .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
19575 .setPackage(mAppPredictionServicePackage);
19576 mContext.sendBroadcastAsUser(predictorIntent, UserHandle.of(launcherUid));
19582 * Report the 'Home' activity which is currently set as "always use this one". If non is set
19583 * then reports the most likely home activity or null if there are more than one.
19585 private ComponentName getDefaultHomeActivity(int userId) {
19586 List<ResolveInfo> allHomeCandidates = new ArrayList<>();
19587 ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
19592 // Find the launcher with the highest priority and return that component if there are no
19593 // other home activity with the same priority.
19594 int lastPriority = Integer.MIN_VALUE;
19595 ComponentName lastComponent = null;
19596 final int size = allHomeCandidates.size();
19597 for (int i = 0; i < size; i++) {
19598 final ResolveInfo ri = allHomeCandidates.get(i);
19599 if (ri.priority > lastPriority) {
19600 lastComponent = ri.activityInfo.getComponentName();
19601 lastPriority = ri.priority;
19602 } else if (ri.priority == lastPriority) {
19603 // Two components found with same priority.
19604 lastComponent = null;
19607 return lastComponent;
19610 private Intent getHomeIntent() {
19611 Intent intent = new Intent(Intent.ACTION_MAIN);
19612 intent.addCategory(Intent.CATEGORY_HOME);
19613 intent.addCategory(Intent.CATEGORY_DEFAULT);
19617 private IntentFilter getHomeFilter() {
19618 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
19619 filter.addCategory(Intent.CATEGORY_HOME);
19620 filter.addCategory(Intent.CATEGORY_DEFAULT);
19624 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
19626 Intent intent = getHomeIntent();
19627 List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
19628 PackageManager.GET_META_DATA, userId);
19629 allHomeCandidates.clear();
19630 if (resolveInfos == null) {
19633 allHomeCandidates.addAll(resolveInfos);
19635 final String packageName = mPermissionManager.getDefaultHome(userId);
19636 if (packageName == null) {
19639 int resolveInfosSize = resolveInfos.size();
19640 for (int i = 0; i < resolveInfosSize; i++) {
19641 ResolveInfo resolveInfo = resolveInfos.get(i);
19643 if (resolveInfo.activityInfo != null && TextUtils.equals(
19644 resolveInfo.activityInfo.packageName, packageName)) {
19645 return new ComponentName(resolveInfo.activityInfo.packageName,
19646 resolveInfo.activityInfo.name);
19652 /** <b>must not hold {@link #mLock}</b> */
19653 private void updateDefaultHomeNotLocked(SparseBooleanArray userIds) {
19654 if (Thread.holdsLock(mLock)) {
19655 Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
19656 + " is holding mLock", new Throwable());
19658 for (int i = userIds.size() - 1; i >= 0; --i) {
19659 final int userId = userIds.keyAt(i);
19660 updateDefaultHomeNotLocked(userId);
19665 * <b>must not hold {@link #mLock}</b>
19667 * @return Whether the ACTION_PREFERRED_ACTIVITY_CHANGED broadcast has been scheduled.
19669 private boolean updateDefaultHomeNotLocked(int userId) {
19670 if (Thread.holdsLock(mLock)) {
19671 Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
19672 + " is holding mLock", new Throwable());
19674 if (!mSystemReady) {
19675 // We might get called before system is ready because of package changes etc, but
19676 // finding preferred activity depends on settings provider, so we ignore the update
19680 final Intent intent = getHomeIntent();
19681 final List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
19682 PackageManager.GET_META_DATA, userId);
19683 final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(
19684 intent, null, 0, resolveInfos, 0, true, false, false, userId);
19685 final String packageName = preferredResolveInfo != null
19686 && preferredResolveInfo.activityInfo != null
19687 ? preferredResolveInfo.activityInfo.packageName : null;
19688 final String currentPackageName = mPermissionManager.getDefaultHome(userId);
19689 if (TextUtils.equals(currentPackageName, packageName)) {
19692 final String[] callingPackages = getPackagesForUid(Binder.getCallingUid());
19693 if (callingPackages != null && ArrayUtils.contains(callingPackages,
19694 mRequiredPermissionControllerPackage)) {
19695 // PermissionController manages default home directly.
19698 mPermissionManager.setDefaultHome(packageName, userId, (successful) -> {
19700 postPreferredActivityChangedBroadcast(userId);
19707 public void setHomeActivity(ComponentName comp, int userId) {
19708 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19711 ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
19712 getHomeActivitiesAsUser(homeActivities, userId);
19714 boolean found = false;
19716 final int size = homeActivities.size();
19717 final ComponentName[] set = new ComponentName[size];
19718 for (int i = 0; i < size; i++) {
19719 final ResolveInfo candidate = homeActivities.get(i);
19720 final ActivityInfo info = candidate.activityInfo;
19721 final ComponentName activityName = new ComponentName(info.packageName, info.name);
19722 set[i] = activityName;
19723 if (!found && activityName.equals(comp)) {
19728 throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
19731 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
19732 set, comp, userId);
19735 private @Nullable String getSetupWizardPackageNameImpl() {
19736 final Intent intent = new Intent(Intent.ACTION_MAIN);
19737 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
19739 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19740 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19741 | MATCH_DISABLED_COMPONENTS,
19742 UserHandle.myUserId());
19743 if (matches.size() == 1) {
19744 return matches.get(0).getComponentInfo().packageName;
19746 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
19747 + ": matches=" + matches);
19752 private @Nullable String getStorageManagerPackageName() {
19753 final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
19755 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19756 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19757 | MATCH_DISABLED_COMPONENTS,
19758 UserHandle.myUserId());
19759 if (matches.size() == 1) {
19760 return matches.get(0).getComponentInfo().packageName;
19762 Slog.e(TAG, "There should probably be exactly one storage manager; found "
19763 + matches.size() + ": matches=" + matches);
19769 public String getDefaultTextClassifierPackageName() {
19770 return ensureSystemPackageName(
19771 mContext.getString(R.string.config_servicesExtensionPackage));
19775 public String getSystemTextClassifierPackageName() {
19776 return ensureSystemPackageName(
19777 mContext.getString(R.string.config_defaultTextClassifierPackage));
19781 public @Nullable String getAttentionServicePackageName() {
19782 final String flattenedComponentName =
19783 mContext.getString(R.string.config_defaultAttentionService);
19784 if (flattenedComponentName != null) {
19785 ComponentName componentName = ComponentName.unflattenFromString(flattenedComponentName);
19786 if (componentName != null && componentName.getPackageName() != null) {
19787 return ensureSystemPackageName(componentName.getPackageName());
19793 private @Nullable String getDocumenterPackageName() {
19794 final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
19795 intent.addCategory(Intent.CATEGORY_OPENABLE);
19796 intent.setType("*/*");
19797 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
19799 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, resolvedType,
19800 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19801 | MATCH_DISABLED_COMPONENTS,
19802 UserHandle.myUserId());
19803 if (matches.size() == 1) {
19804 return matches.get(0).getComponentInfo().packageName;
19806 Slog.e(TAG, "There should probably be exactly one documenter; found "
19807 + matches.size() + ": matches=" + matches);
19813 private String getDeviceConfiguratorPackageName() {
19814 return ensureSystemPackageName(mContext.getString(
19815 R.string.config_deviceConfiguratorPackageName));
19819 public String getWellbeingPackageName() {
19820 return ensureSystemPackageName(mContext.getString(R.string.config_defaultWellbeingPackage));
19824 public String getAppPredictionServicePackageName() {
19825 String flattenedAppPredictionServiceComponentName =
19826 mContext.getString(R.string.config_defaultAppPredictionService);
19827 if (flattenedAppPredictionServiceComponentName == null) {
19830 ComponentName appPredictionServiceComponentName =
19831 ComponentName.unflattenFromString(flattenedAppPredictionServiceComponentName);
19832 if (appPredictionServiceComponentName == null) {
19835 return ensureSystemPackageName(appPredictionServiceComponentName.getPackageName());
19838 private @NonNull String[] dropNonSystemPackages(@NonNull String[] pkgNames) {
19839 return emptyIfNull(filter(pkgNames, String[]::new, mIsSystemPackage), String.class);
19842 private Predicate<String> mIsSystemPackage = (pkgName) -> {
19843 if ("android".equals(pkgName)) {
19846 AndroidPackage pkg = mPackages.get(pkgName);
19847 return pkg != null && pkg.isSystem();
19851 public String getSystemCaptionsServicePackageName() {
19852 String flattenedSystemCaptionsServiceComponentName =
19853 mContext.getString(R.string.config_defaultSystemCaptionsService);
19855 if (TextUtils.isEmpty(flattenedSystemCaptionsServiceComponentName)) {
19859 ComponentName systemCaptionsServiceComponentName =
19860 ComponentName.unflattenFromString(flattenedSystemCaptionsServiceComponentName);
19861 if (systemCaptionsServiceComponentName == null) {
19864 return ensureSystemPackageName(systemCaptionsServiceComponentName.getPackageName());
19868 public String getSetupWizardPackageName() {
19869 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19870 throw new SecurityException("Non-system caller");
19872 return mPmInternal.getSetupWizardPackageName();
19875 public String getIncidentReportApproverPackageName() {
19876 return ensureSystemPackageName(mContext.getString(
19877 R.string.config_incidentReportApproverPackage));
19881 public String[] getTelephonyPackageNames() {
19882 String names = mContext.getString(R.string.config_telephonyPackages);
19883 String[] telephonyPackageNames = null;
19884 if (!TextUtils.isEmpty(names)) {
19885 telephonyPackageNames = names.trim().split(",");
19887 return ensureSystemPackageNames(telephonyPackageNames);
19891 public String getContentCaptureServicePackageName() {
19892 final String flattenedContentCaptureService =
19893 mContext.getString(R.string.config_defaultContentCaptureService);
19895 if (TextUtils.isEmpty(flattenedContentCaptureService)) {
19899 final ComponentName contentCaptureServiceComponentName =
19900 ComponentName.unflattenFromString(flattenedContentCaptureService);
19901 if (contentCaptureServiceComponentName == null) {
19904 return ensureSystemPackageName(contentCaptureServiceComponentName.getPackageName());
19908 private String getRetailDemoPackageName() {
19909 final String predefinedPkgName = mContext.getString(R.string.config_retailDemoPackage);
19910 final String predefinedSignature = mContext.getString(
19911 R.string.config_retailDemoPackageSignature);
19913 if (TextUtils.isEmpty(predefinedPkgName) || TextUtils.isEmpty(predefinedSignature)) {
19917 final AndroidPackage androidPkg = mPackages.get(predefinedPkgName);
19918 if (androidPkg != null) {
19919 final SigningDetails signingDetail = androidPkg.getSigningDetails();
19920 if (signingDetail != null && signingDetail.signatures != null) {
19922 final MessageDigest msgDigest = MessageDigest.getInstance("SHA-256");
19923 for (Signature signature : signingDetail.signatures) {
19924 if (TextUtils.equals(predefinedSignature,
19925 HexEncoding.encodeToString(msgDigest.digest(
19926 signature.toByteArray()), false))) {
19927 return predefinedPkgName;
19930 } catch (NoSuchAlgorithmException e) {
19933 "Unable to verify signatures as getting the retail demo package name",
19943 private String ensureSystemPackageName(@Nullable String packageName) {
19944 if (packageName == null) {
19947 long token = Binder.clearCallingIdentity();
19949 if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) {
19953 Binder.restoreCallingIdentity(token);
19955 return packageName;
19959 private String[] ensureSystemPackageNames(@Nullable String[] packageNames) {
19960 if (packageNames == null) {
19963 final int packageNamesLength = packageNames.length;
19964 for (int i = 0; i < packageNamesLength; i++) {
19965 packageNames[i] = ensureSystemPackageName(packageNames[i]);
19967 return ArrayUtils.filterNotNull(packageNames, String[]::new);
19971 public void setApplicationEnabledSetting(String appPackageName,
19972 int newState, int flags, int userId, String callingPackage) {
19973 if (!mUserManager.exists(userId)) return;
19974 if (callingPackage == null) {
19975 callingPackage = Integer.toString(Binder.getCallingUid());
19977 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
19981 public void setUpdateAvailable(String packageName, boolean updateAvailable) {
19982 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
19983 synchronized (mLock) {
19984 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
19985 if (pkgSetting != null) {
19986 pkgSetting.setUpdateAvailable(updateAvailable);
19992 public void setComponentEnabledSetting(ComponentName componentName,
19993 int newState, int flags, int userId) {
19994 if (!mUserManager.exists(userId)) return;
19995 setEnabledSetting(componentName.getPackageName(),
19996 componentName.getClassName(), newState, flags, userId, null);
19999 private void setEnabledSetting(final String packageName, String className, int newState,
20000 final int flags, int userId, String callingPackage) {
20001 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
20002 || newState == COMPONENT_ENABLED_STATE_ENABLED
20003 || newState == COMPONENT_ENABLED_STATE_DISABLED
20004 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20005 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
20006 throw new IllegalArgumentException("Invalid new component state: "
20009 PackageSetting pkgSetting;
20010 final int callingUid = Binder.getCallingUid();
20011 final int permission;
20012 if (callingUid == Process.SYSTEM_UID) {
20013 permission = PackageManager.PERMISSION_GRANTED;
20015 permission = mContext.checkCallingOrSelfPermission(
20016 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20018 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20019 false /* requireFullPermission */, true /* checkShell */, "set enabled");
20020 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20021 boolean sendNow = false;
20022 boolean isApp = (className == null);
20023 final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
20024 String componentName = isApp ? packageName : className;
20025 ArrayList<String> components;
20028 synchronized (mLock) {
20029 pkgSetting = mSettings.mPackages.get(packageName);
20030 if (pkgSetting == null) {
20031 if (!isCallerInstantApp) {
20032 if (className == null) {
20033 throw new IllegalArgumentException("Unknown package: " + packageName);
20035 throw new IllegalArgumentException(
20036 "Unknown component: " + packageName + "/" + className);
20038 // throw SecurityException to prevent leaking package information
20039 throw new SecurityException(
20040 "Attempt to change component state; "
20041 + "pid=" + Binder.getCallingPid()
20042 + ", uid=" + callingUid
20043 + (className == null
20044 ? ", package=" + packageName
20045 : ", component=" + packageName + "/" + className));
20050 // Limit who can change which apps
20051 if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
20052 // Don't allow apps that don't have permission to modify other apps
20053 if (!allowedByPermission
20054 || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
20055 throw new SecurityException(
20056 "Attempt to change component state; "
20057 + "pid=" + Binder.getCallingPid()
20058 + ", uid=" + callingUid
20059 + (className == null
20060 ? ", package=" + packageName
20061 : ", component=" + packageName + "/" + className));
20063 // Don't allow changing protected packages.
20064 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20065 throw new SecurityException("Cannot disable a protected package: " + packageName);
20068 // Only allow apps with CHANGE_COMPONENT_ENABLED_STATE permission to change hidden
20069 // app details activity
20070 if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)
20071 && !allowedByPermission) {
20072 throw new SecurityException("Cannot disable a system-generated component");
20075 synchronized (mLock) {
20076 if (callingUid == Process.SHELL_UID
20077 && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20078 // Shell can only change whole packages between ENABLED and DISABLED_USER states
20079 // unless it is a test package.
20080 int oldState = pkgSetting.getEnabled(userId);
20081 if (className == null
20083 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20084 || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20085 || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20087 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20088 || newState == COMPONENT_ENABLED_STATE_DEFAULT
20089 || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20092 throw new SecurityException(
20093 "Shell cannot change component state for " + packageName + "/"
20094 + className + " to " + newState);
20098 if (className == null) {
20099 // We're dealing with an application/package level state change
20100 synchronized (mLock) {
20101 if (pkgSetting.getEnabled(userId) == newState) {
20106 // If we're enabling a system stub, there's a little more work to do.
20107 // Prior to enabling the package, we need to decompress the APK(s) to the
20108 // data partition and then replace the version on the system partition.
20109 final AndroidPackage deletedPkg = pkgSetting.pkg;
20110 final boolean isSystemStub = deletedPkg.isStub()
20111 && deletedPkg.isSystem();
20113 && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20114 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
20115 if (!enableCompressedPackage(deletedPkg, pkgSetting)) {
20119 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20120 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20121 // Don't care about who enables an app.
20122 callingPackage = null;
20124 synchronized (mLock) {
20125 pkgSetting.setEnabled(newState, userId, callingPackage);
20126 if (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20127 || newState == COMPONENT_ENABLED_STATE_DISABLED
20128 && pkgSetting.getPermissionsState().hasPermission(
20129 Manifest.permission.SUSPEND_APPS, userId)) {
20130 // This app should not generally be allowed to get disabled by the UI, but if it
20131 // ever does, we don't want to end up with some of the user's apps permanently
20133 unsuspendForSuspendingPackage(packageName, userId);
20134 removeAllDistractingPackageRestrictions(userId);
20138 synchronized (mLock) {
20139 // We're dealing with a component level state change
20140 // First, verify that this is a valid class name.
20141 AndroidPackage pkg = pkgSetting.pkg;
20142 if (pkg == null || !AndroidPackageUtils.hasComponentClassName(pkg, className)) {
20144 pkg.getTargetSdkVersion() >=
20145 Build.VERSION_CODES.JELLY_BEAN) {
20146 throw new IllegalArgumentException("Component class " + className
20147 + " does not exist in " + packageName);
20149 Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20150 + className + " does not exist in " + packageName);
20153 switch (newState) {
20154 case COMPONENT_ENABLED_STATE_ENABLED:
20155 if (!pkgSetting.enableComponentLPw(className, userId)) {
20159 case COMPONENT_ENABLED_STATE_DISABLED:
20160 if (!pkgSetting.disableComponentLPw(className, userId)) {
20164 case COMPONENT_ENABLED_STATE_DEFAULT:
20165 if (!pkgSetting.restoreComponentLPw(className, userId)) {
20170 Slog.e(TAG, "Invalid new component state: " + newState);
20175 synchronized (mLock) {
20176 if ((flags & PackageManager.SYNCHRONOUS) != 0) {
20177 flushPackageRestrictionsAsUserInternalLocked(userId);
20179 scheduleWritePackageRestrictionsLocked(userId);
20181 updateSequenceNumberLP(pkgSetting, new int[] { userId });
20182 final long callingId = Binder.clearCallingIdentity();
20184 updateInstantAppInstallerLocked(packageName);
20186 Binder.restoreCallingIdentity(callingId);
20188 components = mPendingBroadcasts.get(userId, packageName);
20189 final boolean newPackage = components == null;
20191 components = new ArrayList<>();
20193 if (!components.contains(componentName)) {
20194 components.add(componentName);
20196 if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20198 // Purge entry from pending broadcast list if another one exists already
20199 // since we are sending one right away.
20200 mPendingBroadcasts.remove(userId, packageName);
20203 mPendingBroadcasts.put(userId, packageName, components);
20205 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20206 // Schedule a message - if it has been a "reasonably long time" since the
20207 // service started, send the broadcast with a delay of one second to avoid
20208 // delayed reactions from the receiver, else keep the default ten second delay
20209 // to avoid extreme thrashing on service startup.
20210 final long broadcastDelay = SystemClock.uptimeMillis() > mServiceStartWithDelay
20212 : BROADCAST_DELAY_DURING_STARTUP;
20213 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, broadcastDelay);
20218 long callingId = Binder.clearCallingIdentity();
20221 int packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20222 sendPackageChangedBroadcast(packageName,
20223 (flags & PackageManager.DONT_KILL_APP) != 0, components, packageUid, null);
20226 Binder.restoreCallingIdentity(callingId);
20232 public void flushPackageRestrictionsAsUser(int userId) {
20233 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20236 if (!mUserManager.exists(userId)) {
20239 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20240 false /* checkShell */, "flushPackageRestrictions");
20241 synchronized (mLock) {
20242 flushPackageRestrictionsAsUserInternalLocked(userId);
20246 @GuardedBy("mLock")
20247 private void flushPackageRestrictionsAsUserInternalLocked(int userId) {
20248 // NOTE: this invokes synchronous disk access, so callers using this
20249 // method should consider running on a background thread
20250 mSettings.writePackageRestrictionsLPr(userId);
20251 mDirtyUsers.remove(userId);
20252 if (mDirtyUsers.isEmpty()) {
20253 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20257 private void sendPackageChangedBroadcast(String packageName,
20258 boolean dontKillApp, ArrayList<String> componentNames, int packageUid,
20261 Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20263 Bundle extras = new Bundle(4);
20264 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20265 String nameList[] = new String[componentNames.size()];
20266 componentNames.toArray(nameList);
20267 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
20268 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, dontKillApp);
20269 extras.putInt(Intent.EXTRA_UID, packageUid);
20270 if (reason != null) {
20271 extras.putString(Intent.EXTRA_REASON, reason);
20273 // If this is not reporting a change of the overall package, then only send it
20274 // to registered receivers. We don't want to launch a swath of apps for every
20275 // little component state change.
20276 final int flags = !componentNames.contains(packageName)
20277 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
20278 final int userId = UserHandle.getUserId(packageUid);
20279 final boolean isInstantApp = isInstantApp(packageName, userId);
20280 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
20281 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
20282 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null,
20283 userIds, instantUserIds);
20287 public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
20288 if (!mUserManager.exists(userId)) return;
20289 final int callingUid = Binder.getCallingUid();
20290 if (getInstantAppPackageName(callingUid) != null) {
20293 final int permission = mContext.checkCallingOrSelfPermission(
20294 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20295 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20296 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20297 true /* requireFullPermission */, true /* checkShell */, "stop package");
20299 synchronized (mLock) {
20300 final PackageSetting ps = mSettings.mPackages.get(packageName);
20301 if (!shouldFilterApplicationLocked(ps, callingUid, userId)
20302 && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
20303 allowedByPermission, callingUid, userId)) {
20304 scheduleWritePackageRestrictionsLocked(userId);
20310 public String getInstallerPackageName(String packageName) {
20311 final int callingUid = Binder.getCallingUid();
20312 synchronized (mLock) {
20313 final InstallSource installSource = getInstallSourceLocked(packageName, callingUid);
20314 if (installSource == null) {
20315 throw new IllegalArgumentException("Unknown package: " + packageName);
20317 String installerPackageName = installSource.installerPackageName;
20318 if (installerPackageName != null) {
20319 final PackageSetting ps = mSettings.mPackages.get(installerPackageName);
20320 if (ps == null || shouldFilterApplicationLocked(ps, callingUid,
20321 UserHandle.getUserId(callingUid))) {
20322 installerPackageName = null;
20325 return installerPackageName;
20331 public InstallSourceInfo getInstallSourceInfo(String packageName) {
20332 final int callingUid = Binder.getCallingUid();
20333 final int userId = UserHandle.getUserId(callingUid);
20335 String installerPackageName;
20336 String initiatingPackageName;
20337 String originatingPackageName;
20339 final InstallSource installSource;
20340 synchronized (mLock) {
20341 installSource = getInstallSourceLocked(packageName, callingUid);
20342 if (installSource == null) {
20346 installerPackageName = installSource.installerPackageName;
20347 if (installerPackageName != null) {
20348 final PackageSetting ps = mSettings.mPackages.get(installerPackageName);
20349 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
20350 installerPackageName = null;
20354 if (installSource.isInitiatingPackageUninstalled) {
20355 // We can't check visibility in the usual way, since the initiating package is no
20356 // longer present. So we apply simpler rules to whether to expose the info:
20357 // 1. Instant apps can't see it.
20358 // 2. Otherwise only the installed app itself can see it.
20359 final boolean isInstantApp = getInstantAppPackageName(callingUid) != null;
20360 if (!isInstantApp && isCallerSameApp(packageName, callingUid)) {
20361 initiatingPackageName = installSource.initiatingPackageName;
20363 initiatingPackageName = null;
20366 // All installSource strings are interned, so == is ok here
20367 if (installSource.initiatingPackageName == installSource.installerPackageName) {
20368 // The installer and initiator will often be the same, and when they are
20369 // we can skip doing the same check again.
20370 initiatingPackageName = installerPackageName;
20372 initiatingPackageName = installSource.initiatingPackageName;
20373 final PackageSetting ps = mSettings.mPackages.get(initiatingPackageName);
20374 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
20375 initiatingPackageName = null;
20380 originatingPackageName = installSource.originatingPackageName;
20381 if (originatingPackageName != null) {
20382 final PackageSetting ps = mSettings.mPackages.get(originatingPackageName);
20383 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
20384 originatingPackageName = null;
20389 // Remaining work can safely be done outside the lock. (Note that installSource is
20390 // immutable so it's ok to carry on reading from it.)
20392 if (originatingPackageName != null && mContext.checkCallingOrSelfPermission(
20393 Manifest.permission.INSTALL_PACKAGES) != PackageManager.PERMISSION_GRANTED) {
20394 originatingPackageName = null;
20397 // If you can see the initiatingPackageName, and we have valid signing info for it,
20398 // then we let you see that too.
20399 final SigningInfo initiatingPackageSigningInfo;
20400 final PackageSignatures signatures = installSource.initiatingPackageSignatures;
20401 if (initiatingPackageName != null && signatures != null
20402 && signatures.mSigningDetails != SigningDetails.UNKNOWN) {
20403 initiatingPackageSigningInfo = new SigningInfo(signatures.mSigningDetails);
20405 initiatingPackageSigningInfo = null;
20408 return new InstallSourceInfo(initiatingPackageName, initiatingPackageSigningInfo,
20409 originatingPackageName, installerPackageName);
20412 @GuardedBy("mLock")
20414 private InstallSource getInstallSourceLocked(String packageName, int callingUid) {
20415 final PackageSetting ps = mSettings.mPackages.get(packageName);
20417 // Installer info for Apex is not stored in PackageManager
20418 if (ps == null && mApexManager.isApexPackage(packageName)) {
20419 return InstallSource.EMPTY;
20422 if (ps == null || shouldFilterApplicationLocked(ps, callingUid,
20423 UserHandle.getUserId(callingUid))) {
20427 return ps.installSource;
20430 public boolean isOrphaned(String packageName) {
20432 synchronized (mLock) {
20433 if (!mPackages.containsKey(packageName)) {
20436 return mSettings.isOrphaned(packageName);
20441 public int getApplicationEnabledSetting(String packageName, int userId) {
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 */, "get enabled");
20447 synchronized (mLock) {
20448 if (shouldFilterApplicationLocked(
20449 mSettings.getPackageLPr(packageName), callingUid, userId)) {
20450 return COMPONENT_ENABLED_STATE_DISABLED;
20452 return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20457 public int getComponentEnabledSetting(@NonNull ComponentName component, int userId) {
20458 if (component == null) return COMPONENT_ENABLED_STATE_DEFAULT;
20459 if (!mUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20460 int callingUid = Binder.getCallingUid();
20461 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20462 false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
20463 synchronized (mLock) {
20464 if (shouldFilterApplicationLocked(
20465 mSettings.getPackageLPr(component.getPackageName()), callingUid,
20466 component, TYPE_UNKNOWN, userId)) {
20467 return COMPONENT_ENABLED_STATE_DISABLED;
20469 return mSettings.getComponentEnabledSettingLPr(component, userId);
20474 public void enterSafeMode() {
20475 enforceSystemOrRoot("Only the system can request entering safe mode");
20477 if (!mSystemReady) {
20483 public void systemReady() {
20484 enforceSystemOrRoot("Only the system can claim the system is ready");
20486 mSystemReady = true;
20487 final ContentResolver resolver = mContext.getContentResolver();
20488 ContentObserver co = new ContentObserver(mHandler) {
20490 public void onChange(boolean selfChange) {
20491 final boolean ephemeralFeatureDisabled =
20492 Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0;
20493 for (int userId : UserManagerService.getInstance().getUserIds()) {
20494 final boolean instantAppsDisabledForUser =
20495 ephemeralFeatureDisabled || Secure.getIntForUser(resolver,
20496 Secure.INSTANT_APPS_ENABLED, 1, userId) == 0;
20497 mWebInstantAppsDisabled.put(userId, instantAppsDisabledForUser);
20501 mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20502 .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20503 false, co, UserHandle.USER_ALL);
20504 mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure
20505 .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL);
20508 mAppsFilter.onSystemReady();
20510 // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20511 // disabled after already being started.
20512 CarrierAppUtils.disableCarrierAppsUntilPrivileged(
20513 mContext.getOpPackageName(), UserHandle.USER_SYSTEM, mContext);
20515 disableSkuSpecificApps();
20517 // Read the compatibilty setting when the system is ready.
20518 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20519 mContext.getContentResolver(),
20520 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20521 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20523 if (DEBUG_SETTINGS) {
20524 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20527 synchronized (mLock) {
20528 // Verify that all of the preferred activity components actually
20529 // exist. It is possible for applications to be updated and at
20530 // that point remove a previously declared activity component that
20531 // had been set as a preferred activity. We try to clean this up
20532 // the next time we encounter that preferred activity, but it is
20533 // possible for the user flow to never be able to return to that
20534 // situation so here we do a sanity check to make sure we haven't
20535 // left any junk around.
20536 ArrayList<PreferredActivity> removed = new ArrayList<>();
20537 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20538 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20540 for (PreferredActivity pa : pir.filterSet()) {
20541 if (!mComponentResolver.isActivityDefined(pa.mPref.mComponent)) {
20545 if (removed.size() > 0) {
20546 for (int r=0; r<removed.size(); r++) {
20547 PreferredActivity pa = removed.get(r);
20548 Slog.w(TAG, "Removing dangling preferred activity: "
20549 + pa.mPref.mComponent);
20550 pir.removeFilter(pa);
20552 mSettings.writePackageRestrictionsLPr(
20553 mSettings.mPreferredActivities.keyAt(i));
20558 mUserManager.systemReady();
20560 // Now that we've scanned all packages, and granted any default
20561 // permissions, ensure permissions are updated. Beware of dragons if you
20562 // try optimizing this.
20563 synchronized (mLock) {
20564 mPermissionManager.updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, false);
20566 final PermissionPolicyInternal permissionPolicyInternal =
20567 mInjector.getPermissionPolicyInternal();
20568 permissionPolicyInternal.setOnInitializedCallback(userId -> {
20569 // The SDK updated case is already handled when we run during the ctor.
20570 synchronized (mLock) {
20571 mPermissionManager.updateAllPermissions(
20572 StorageManager.UUID_PRIVATE_INTERNAL, false);
20577 // Watch for external volumes that come and go over time
20578 final StorageManager storage = mInjector.getStorageManager();
20579 storage.registerListener(mStorageListener);
20581 mInstallerService.systemReady();
20582 mApexManager.systemReady(mContext);
20583 mPackageDexOptimizer.systemReady();
20585 mInjector.getStorageManagerInternal().addExternalStoragePolicy(
20586 new StorageManagerInternal.ExternalStorageMountPolicy() {
20588 public int getMountMode(int uid, String packageName) {
20589 if (Process.isIsolated(uid)) {
20590 return Zygote.MOUNT_EXTERNAL_NONE;
20592 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20593 return Zygote.MOUNT_EXTERNAL_DEFAULT;
20595 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20596 return Zygote.MOUNT_EXTERNAL_READ;
20598 return Zygote.MOUNT_EXTERNAL_WRITE;
20602 public boolean hasExternalStorage(int uid, String packageName) {
20607 // Now that we're mostly running, clean up stale users and apps
20608 mUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20609 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20611 mPermissionManager.systemReady();
20613 if (mInstantAppResolverConnection != null) {
20614 mContext.registerReceiver(new BroadcastReceiver() {
20616 public void onReceive(Context context, Intent intent) {
20617 mInstantAppResolverConnection.optimisticBind();
20618 mContext.unregisterReceiver(this);
20620 }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
20623 IntentFilter overlayFilter = new IntentFilter(Intent.ACTION_OVERLAY_CHANGED);
20624 overlayFilter.addDataScheme("package");
20625 mContext.registerReceiver(new BroadcastReceiver() {
20627 public void onReceive(Context context, Intent intent) {
20628 if (intent == null) {
20631 Uri data = intent.getData();
20632 if (data == null) {
20635 String packageName = data.getSchemeSpecificPart();
20636 if (packageName == null) {
20639 AndroidPackage pkg = mPackages.get(packageName);
20643 sendPackageChangedBroadcast(pkg.getPackageName(),
20644 true /* dontKillApp */,
20645 new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
20647 Intent.ACTION_OVERLAY_CHANGED);
20651 mModuleInfoProvider.systemReady();
20653 // Installer service might attempt to install some packages that have been staged for
20654 // installation on reboot. Make sure this is the last component to be call since the
20655 // installation might require other components to be ready.
20656 mInstallerService.restoreAndApplyStagedSessionIfNeeded();
20659 public void waitForAppDataPrepared() {
20660 if (mPrepareAppDataFuture == null) {
20663 ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20664 mPrepareAppDataFuture = null;
20668 public boolean isSafeMode() {
20669 // allow instant applications
20674 public boolean hasSystemUidErrors() {
20675 // allow instant applications
20676 return mHasSystemUidErrors;
20679 static String arrayToString(int[] array) {
20680 StringBuilder stringBuilder = new StringBuilder(128);
20681 stringBuilder.append('[');
20682 if (array != null) {
20683 for (int i=0; i<array.length; i++) {
20684 if (i > 0) stringBuilder.append(", ");
20685 stringBuilder.append(array[i]);
20688 stringBuilder.append(']');
20689 return stringBuilder.toString();
20693 public void onShellCommand(FileDescriptor in, FileDescriptor out,
20694 FileDescriptor err, String[] args, ShellCallback callback,
20695 ResultReceiver resultReceiver) {
20696 (new PackageManagerShellCommand(this, mPermissionManagerService)).exec(
20697 this, in, out, err, args, callback, resultReceiver);
20700 @SuppressWarnings("resource")
20702 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20703 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
20705 DumpState dumpState = new DumpState();
20706 boolean fullPreferred = false;
20707 boolean checkin = false;
20709 String packageName = null;
20710 ArraySet<String> permissionNames = null;
20713 while (opti < args.length) {
20714 String opt = args[opti];
20715 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
20720 if ("-a".equals(opt)) {
20721 // Right now we only know how to print all.
20722 } else if ("-h".equals(opt)) {
20723 pw.println("Package manager dump options:");
20724 pw.println(" [-h] [-f] [--checkin] [--all-components] [cmd] ...");
20725 pw.println(" --checkin: dump for a checkin");
20726 pw.println(" -f: print details of intent filters");
20727 pw.println(" -h: print this help");
20728 pw.println(" --all-components: include all component names in package dump");
20729 pw.println(" cmd may be one of:");
20730 pw.println(" apex: list active APEXes and APEX session state");
20731 pw.println(" l[ibraries]: list known shared libraries");
20732 pw.println(" f[eatures]: list device features");
20733 pw.println(" k[eysets]: print known keysets");
20734 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
20735 pw.println(" perm[issions]: dump permissions");
20736 pw.println(" permission [name ...]: dump declaration and use of given permission");
20737 pw.println(" pref[erred]: print preferred package settings");
20738 pw.println(" preferred-xml [--full]: print preferred package settings as xml");
20739 pw.println(" prov[iders]: dump content providers");
20740 pw.println(" p[ackages]: dump installed packages");
20741 pw.println(" q[ueries]: dump app queryability calculations");
20742 pw.println(" s[hared-users]: dump shared user IDs");
20743 pw.println(" m[essages]: print collected runtime messages");
20744 pw.println(" v[erifiers]: print package verifier info");
20745 pw.println(" d[omain-preferred-apps]: print domains preferred apps");
20746 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
20747 pw.println(" version: print database version info");
20748 pw.println(" write: write current settings now");
20749 pw.println(" installs: details about install sessions");
20750 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?");
20751 pw.println(" dexopt: dump dexopt state");
20752 pw.println(" compiler-stats: dump compiler statistics");
20753 pw.println(" service-permissions: dump permissions required by services");
20754 pw.println(" <package.name>: info about given package");
20756 } else if ("--checkin".equals(opt)) {
20758 } else if ("--all-components".equals(opt)) {
20759 dumpState.setOptionEnabled(DumpState.OPTION_DUMP_ALL_COMPONENTS);
20760 } else if ("-f".equals(opt)) {
20761 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20762 } else if ("--proto".equals(opt)) {
20766 pw.println("Unknown argument: " + opt + "; use -h for help");
20770 // Is the caller requesting to dump a particular piece of data?
20771 if (opti < args.length) {
20772 String cmd = args[opti];
20774 // Is this a package name?
20775 if ("android".equals(cmd) || cmd.contains(".")) {
20777 // When dumping a single package, we always dump all of its
20778 // filter information since the amount of data will be reasonable.
20779 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20780 } else if ("check-permission".equals(cmd)) {
20781 if (opti >= args.length) {
20782 pw.println("Error: check-permission missing permission argument");
20785 String perm = args[opti];
20787 if (opti >= args.length) {
20788 pw.println("Error: check-permission missing package argument");
20792 String pkg = args[opti];
20794 int user = UserHandle.getUserId(Binder.getCallingUid());
20795 if (opti < args.length) {
20797 user = Integer.parseInt(args[opti]);
20798 } catch (NumberFormatException e) {
20799 pw.println("Error: check-permission user argument is not a number: "
20805 // Normalize package name to handle renamed packages and static libs
20806 pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
20808 pw.println(checkPermission(perm, pkg, user));
20810 } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
20811 dumpState.setDump(DumpState.DUMP_LIBS);
20812 } else if ("f".equals(cmd) || "features".equals(cmd)) {
20813 dumpState.setDump(DumpState.DUMP_FEATURES);
20814 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
20815 if (opti >= args.length) {
20816 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
20817 | DumpState.DUMP_SERVICE_RESOLVERS
20818 | DumpState.DUMP_RECEIVER_RESOLVERS
20819 | DumpState.DUMP_CONTENT_RESOLVERS);
20821 while (opti < args.length) {
20822 String name = args[opti];
20823 if ("a".equals(name) || "activity".equals(name)) {
20824 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
20825 } else if ("s".equals(name) || "service".equals(name)) {
20826 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
20827 } else if ("r".equals(name) || "receiver".equals(name)) {
20828 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
20829 } else if ("c".equals(name) || "content".equals(name)) {
20830 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
20832 pw.println("Error: unknown resolver table type: " + name);
20838 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
20839 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
20840 } else if ("permission".equals(cmd)) {
20841 if (opti >= args.length) {
20842 pw.println("Error: permission requires permission name");
20845 permissionNames = new ArraySet<>();
20846 while (opti < args.length) {
20847 permissionNames.add(args[opti]);
20850 dumpState.setDump(DumpState.DUMP_PERMISSIONS
20851 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
20852 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
20853 dumpState.setDump(DumpState.DUMP_PREFERRED);
20854 } else if ("preferred-xml".equals(cmd)) {
20855 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
20856 if (opti < args.length && "--full".equals(args[opti])) {
20857 fullPreferred = true;
20860 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
20861 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
20862 } else if ("p".equals(cmd) || "packages".equals(cmd)) {
20863 dumpState.setDump(DumpState.DUMP_PACKAGES);
20864 } else if ("q".equals(cmd) || "queries".equals(cmd)) {
20865 dumpState.setDump(DumpState.DUMP_QUERIES);
20866 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
20867 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
20868 if (opti < args.length && "noperm".equals(args[opti])) {
20869 dumpState.setOptionEnabled(DumpState.OPTION_SKIP_PERMISSIONS);
20871 } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
20872 dumpState.setDump(DumpState.DUMP_PROVIDERS);
20873 } else if ("m".equals(cmd) || "messages".equals(cmd)) {
20874 dumpState.setDump(DumpState.DUMP_MESSAGES);
20875 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
20876 dumpState.setDump(DumpState.DUMP_VERIFIERS);
20877 } else if ("i".equals(cmd) || "ifv".equals(cmd)
20878 || "intent-filter-verifiers".equals(cmd)) {
20879 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
20880 } else if ("version".equals(cmd)) {
20881 dumpState.setDump(DumpState.DUMP_VERSION);
20882 } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
20883 dumpState.setDump(DumpState.DUMP_KEYSETS);
20884 } else if ("installs".equals(cmd)) {
20885 dumpState.setDump(DumpState.DUMP_INSTALLS);
20886 } else if ("frozen".equals(cmd)) {
20887 dumpState.setDump(DumpState.DUMP_FROZEN);
20888 } else if ("volumes".equals(cmd)) {
20889 dumpState.setDump(DumpState.DUMP_VOLUMES);
20890 } else if ("dexopt".equals(cmd)) {
20891 dumpState.setDump(DumpState.DUMP_DEXOPT);
20892 } else if ("compiler-stats".equals(cmd)) {
20893 dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
20894 } else if ("changes".equals(cmd)) {
20895 dumpState.setDump(DumpState.DUMP_CHANGES);
20896 } else if ("service-permissions".equals(cmd)) {
20897 dumpState.setDump(DumpState.DUMP_SERVICE_PERMISSIONS);
20898 } else if ("write".equals(cmd)) {
20899 synchronized (mLock) {
20900 mSettings.writeLPr();
20901 pw.println("Settings written.");
20908 pw.println("vers,1");
20912 synchronized (mLock) {
20913 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
20915 if (dumpState.onTitlePrinted())
20917 pw.println("Database versions:");
20918 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " "));
20922 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
20924 if (dumpState.onTitlePrinted())
20926 pw.println("Verifiers:");
20927 pw.print(" Required: ");
20928 pw.print(mRequiredVerifierPackage);
20929 pw.print(" (uid=");
20930 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20931 UserHandle.USER_SYSTEM));
20933 } else if (mRequiredVerifierPackage != null) {
20934 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
20936 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20937 UserHandle.USER_SYSTEM));
20941 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
20942 packageName == null) {
20943 if (mIntentFilterVerifierComponent != null) {
20944 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
20946 if (dumpState.onTitlePrinted())
20948 pw.println("Intent Filter Verifier:");
20949 pw.print(" Using: ");
20950 pw.print(verifierPackageName);
20951 pw.print(" (uid=");
20952 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20953 UserHandle.USER_SYSTEM));
20955 } else if (verifierPackageName != null) {
20956 pw.print("ifv,"); pw.print(verifierPackageName);
20958 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20959 UserHandle.USER_SYSTEM));
20963 pw.println("No Intent Filter Verifier available!");
20967 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
20968 boolean printedHeader = false;
20969 final Iterator<String> it = mSharedLibraries.keySet().iterator();
20970 while (it.hasNext()) {
20971 String libName = it.next();
20972 LongSparseArray<SharedLibraryInfo> versionedLib
20973 = mSharedLibraries.get(libName);
20974 if (versionedLib == null) {
20977 final int versionCount = versionedLib.size();
20978 for (int i = 0; i < versionCount; i++) {
20979 SharedLibraryInfo libraryInfo = versionedLib.valueAt(i);
20981 if (!printedHeader) {
20982 if (dumpState.onTitlePrinted())
20984 pw.println("Libraries:");
20985 printedHeader = true;
20991 pw.print(libraryInfo.getName());
20992 if (libraryInfo.isStatic()) {
20993 pw.print(" version=" + libraryInfo.getLongVersion());
20998 if (libraryInfo.getPath() != null) {
20999 pw.print(" (jar) ");
21000 pw.print(libraryInfo.getPath());
21002 pw.print(" (apk) ");
21003 pw.print(libraryInfo.getPackageName());
21010 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
21011 if (dumpState.onTitlePrinted())
21014 pw.println("Features:");
21017 synchronized (mAvailableFeatures) {
21018 for (FeatureInfo feat : mAvailableFeatures.values()) {
21021 pw.print(feat.name);
21023 pw.println(feat.version);
21026 pw.print(feat.name);
21027 if (feat.version > 0) {
21028 pw.print(" version=");
21029 pw.print(feat.version);
21037 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
21038 mComponentResolver.dumpActivityResolvers(pw, dumpState, packageName);
21040 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
21041 mComponentResolver.dumpReceiverResolvers(pw, dumpState, packageName);
21043 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
21044 mComponentResolver.dumpServiceResolvers(pw, dumpState, packageName);
21046 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
21047 mComponentResolver.dumpProviderResolvers(pw, dumpState, packageName);
21050 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
21051 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21052 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21053 int user = mSettings.mPreferredActivities.keyAt(i);
21055 dumpState.getTitlePrinted()
21056 ? "\nPreferred Activities User " + user + ":"
21057 : "Preferred Activities User " + user + ":", " ",
21058 packageName, true, false)) {
21059 dumpState.setTitlePrinted(true);
21064 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
21066 FileOutputStream fout = new FileOutputStream(fd);
21067 BufferedOutputStream str = new BufferedOutputStream(fout);
21068 XmlSerializer serializer = new FastXmlSerializer();
21070 serializer.setOutput(str, StandardCharsets.UTF_8.name());
21071 serializer.startDocument(null, true);
21072 serializer.setFeature(
21073 "http://xmlpull.org/v1/doc/features.html#indent-output", true);
21074 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
21075 serializer.endDocument();
21076 serializer.flush();
21077 } catch (IllegalArgumentException e) {
21078 pw.println("Failed writing: " + e);
21079 } catch (IllegalStateException e) {
21080 pw.println("Failed writing: " + e);
21081 } catch (IOException e) {
21082 pw.println("Failed writing: " + e);
21087 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
21088 && packageName == null) {
21090 int count = mSettings.mPackages.size();
21092 pw.println("No applications!");
21095 final String prefix = " ";
21096 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
21097 if (allPackageSettings.size() == 0) {
21098 pw.println("No domain preferred apps!");
21101 pw.println("App verification status:");
21104 for (PackageSetting ps : allPackageSettings) {
21105 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
21106 if (ivi == null || ivi.getPackageName() == null) continue;
21107 pw.println(prefix + "Package: " + ivi.getPackageName());
21108 pw.println(prefix + "Domains: " + ivi.getDomainsString());
21109 pw.println(prefix + "Status: " + ivi.getStatusString());
21114 pw.println(prefix + "No app verification established.");
21117 for (int userId : mUserManager.getUserIds()) {
21118 pw.println("App linkages for user " + userId + ":");
21121 for (PackageSetting ps : allPackageSettings) {
21122 final long status = ps.getDomainVerificationStatusForUser(userId);
21123 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
21124 && !DEBUG_DOMAIN_VERIFICATION) {
21127 pw.println(prefix + "Package: " + ps.name);
21128 pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
21129 String statusStr = IntentFilterVerificationInfo.
21130 getStatusStringFromValue(status);
21131 pw.println(prefix + "Status: " + statusStr);
21136 pw.println(prefix + "No configured app linkages.");
21144 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21145 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21148 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21149 mComponentResolver.dumpContentProviders(pw, dumpState, packageName);
21152 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21153 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21156 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21157 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21160 if (dumpState.isDumping(DumpState.DUMP_QUERIES)) {
21161 final PackageSetting setting = mSettings.getPackageLPr(packageName);
21162 Integer filteringAppId = setting == null ? null : setting.appId;
21163 mAppsFilter.dumpQueries(
21164 pw, this, filteringAppId, dumpState,
21165 mUserManager.getUserIds());
21168 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21169 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21172 if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
21173 if (dumpState.onTitlePrinted()) pw.println();
21174 pw.println("Package Changes:");
21175 pw.print(" Sequence number="); pw.println(mChangedPackagesSequenceNumber);
21176 final int K = mChangedPackages.size();
21177 for (int i = 0; i < K; i++) {
21178 final SparseArray<String> changes = mChangedPackages.valueAt(i);
21179 pw.print(" User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
21180 final int N = changes.size();
21182 pw.print(" "); pw.println("No packages changed");
21184 for (int j = 0; j < N; j++) {
21185 final String pkgName = changes.valueAt(j);
21186 final int sequenceNumber = changes.keyAt(j);
21189 pw.print(sequenceNumber);
21190 pw.print(", package=");
21191 pw.println(pkgName);
21197 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21198 // XXX should handle packageName != null by dumping only install data that
21199 // the given package is involved with.
21200 if (dumpState.onTitlePrinted()) pw.println();
21202 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
21204 ipw.println("Frozen packages:");
21205 ipw.increaseIndent();
21206 if (mFrozenPackages.size() == 0) {
21207 ipw.println("(none)");
21209 for (int i = 0; i < mFrozenPackages.size(); i++) {
21210 ipw.println(mFrozenPackages.valueAt(i));
21213 ipw.decreaseIndent();
21216 if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
21217 if (dumpState.onTitlePrinted()) pw.println();
21219 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
21221 ipw.println("Loaded volumes:");
21222 ipw.increaseIndent();
21223 if (mLoadedVolumes.size() == 0) {
21224 ipw.println("(none)");
21226 for (int i = 0; i < mLoadedVolumes.size(); i++) {
21227 ipw.println(mLoadedVolumes.valueAt(i));
21230 ipw.decreaseIndent();
21233 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
21234 && packageName == null) {
21235 mComponentResolver.dumpServicePermissions(pw, dumpState);
21238 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21239 if (dumpState.onTitlePrinted()) pw.println();
21240 dumpDexoptStateLPr(pw, packageName);
21243 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21244 if (dumpState.onTitlePrinted()) pw.println();
21245 dumpCompilerStatsLPr(pw, packageName);
21248 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21249 if (dumpState.onTitlePrinted()) pw.println();
21250 mSettings.dumpReadMessagesLPr(pw, dumpState);
21253 pw.println("Package warning messages:");
21254 dumpCriticalInfo(pw, null);
21257 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21258 dumpCriticalInfo(pw, "msg,");
21262 // PackageInstaller should be called outside of mPackages lock
21263 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21264 // XXX should handle packageName != null by dumping only install data that
21265 // the given package is involved with.
21266 if (dumpState.onTitlePrinted()) pw.println();
21267 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120));
21270 if (!checkin && dumpState.isDumping(DumpState.DUMP_APEX)) {
21271 mApexManager.dump(pw, packageName);
21275 //TODO: b/111402650
21276 private void disableSkuSpecificApps() {
21277 String apkList[] = mContext.getResources().getStringArray(
21278 R.array.config_disableApksUnlessMatchedSku_apk_list);
21279 String skuArray[] = mContext.getResources().getStringArray(
21280 R.array.config_disableApkUnlessMatchedSku_skus_list);
21281 if (ArrayUtils.isEmpty(apkList)) {
21284 String sku = SystemProperties.get("ro.boot.hardware.sku");
21285 if (!TextUtils.isEmpty(sku) && ArrayUtils.contains(skuArray, sku)) {
21288 for (String packageName : apkList) {
21289 setSystemAppHiddenUntilInstalled(packageName, true);
21290 for (UserInfo user : mUserManager.getUsers(false)) {
21291 setSystemAppInstallState(packageName, false, user.id);
21296 private void dumpProto(FileDescriptor fd) {
21297 final ProtoOutputStream proto = new ProtoOutputStream(fd);
21299 synchronized (mLock) {
21300 final long requiredVerifierPackageToken =
21301 proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21302 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21304 PackageServiceDumpProto.PackageShortProto.UID,
21306 mRequiredVerifierPackage,
21307 MATCH_DEBUG_TRIAGED_MISSING,
21308 UserHandle.USER_SYSTEM));
21309 proto.end(requiredVerifierPackageToken);
21311 if (mIntentFilterVerifierComponent != null) {
21312 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21313 final long verifierPackageToken =
21314 proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21315 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21317 PackageServiceDumpProto.PackageShortProto.UID,
21319 verifierPackageName,
21320 MATCH_DEBUG_TRIAGED_MISSING,
21321 UserHandle.USER_SYSTEM));
21322 proto.end(verifierPackageToken);
21325 dumpSharedLibrariesProto(proto);
21326 dumpFeaturesProto(proto);
21327 mSettings.dumpPackagesProto(proto);
21328 mSettings.dumpSharedUsersProto(proto);
21329 dumpCriticalInfo(proto);
21334 private void dumpFeaturesProto(ProtoOutputStream proto) {
21335 synchronized (mAvailableFeatures) {
21336 final int count = mAvailableFeatures.size();
21337 for (int i = 0; i < count; i++) {
21338 mAvailableFeatures.valueAt(i).dumpDebug(proto, PackageServiceDumpProto.FEATURES);
21343 private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21344 final int count = mSharedLibraries.size();
21345 for (int i = 0; i < count; i++) {
21346 final String libName = mSharedLibraries.keyAt(i);
21347 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(libName);
21348 if (versionedLib == null) {
21351 final int versionCount = versionedLib.size();
21352 for (int j = 0; j < versionCount; j++) {
21353 final SharedLibraryInfo libraryInfo = versionedLib.valueAt(j);
21354 final long sharedLibraryToken =
21355 proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21356 proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libraryInfo.getName());
21357 final boolean isJar = (libraryInfo.getPath() != null);
21358 proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21360 proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH,
21361 libraryInfo.getPath());
21363 proto.write(PackageServiceDumpProto.SharedLibraryProto.APK,
21364 libraryInfo.getPackageName());
21366 proto.end(sharedLibraryToken);
21371 @GuardedBy("mLock")
21372 @SuppressWarnings("resource")
21373 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21374 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
21376 ipw.println("Dexopt state:");
21377 ipw.increaseIndent();
21378 Collection<PackageSetting> pkgSettings;
21379 if (packageName != null) {
21380 PackageSetting targetPkgSetting = mSettings.mPackages.get(packageName);
21381 if (targetPkgSetting != null) {
21382 pkgSettings = Collections.singletonList(targetPkgSetting);
21384 ipw.println("Unable to find package: " + packageName);
21388 pkgSettings = mSettings.mPackages.values();
21391 for (PackageSetting pkgSetting : pkgSettings) {
21392 if (pkgSetting.pkg == null) {
21395 ipw.println("[" + pkgSetting.name + "]");
21396 ipw.increaseIndent();
21397 mPackageDexOptimizer.dumpDexoptState(ipw, pkgSetting.pkg, pkgSetting,
21398 mDexManager.getPackageUseInfoOrDefault(pkgSetting.pkg.getPackageName()));
21399 ipw.decreaseIndent();
21403 @GuardedBy("mLock")
21404 @SuppressWarnings("resource")
21405 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
21406 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
21408 ipw.println("Compiler stats:");
21409 ipw.increaseIndent();
21410 Collection<AndroidPackage> packages;
21411 if (packageName != null) {
21412 AndroidPackage targetPackage = mPackages.get(packageName);
21413 if (targetPackage != null) {
21414 packages = Collections.singletonList(targetPackage);
21416 ipw.println("Unable to find package: " + packageName);
21420 packages = mPackages.values();
21423 for (AndroidPackage pkg : packages) {
21424 ipw.println("[" + pkg.getPackageName() + "]");
21425 ipw.increaseIndent();
21427 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.getPackageName());
21428 if (stats == null) {
21429 ipw.println("(No recorded stats)");
21433 ipw.decreaseIndent();
21437 private String dumpDomainString(String packageName) {
21438 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21440 List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21442 ArraySet<String> result = new ArraySet<>();
21443 if (iviList.size() > 0) {
21444 for (IntentFilterVerificationInfo ivi : iviList) {
21445 result.addAll(ivi.getDomains());
21448 if (filters != null && filters.size() > 0) {
21449 for (IntentFilter filter : filters) {
21450 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21451 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21452 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21453 result.addAll(filter.getHostsList());
21458 StringBuilder sb = new StringBuilder(result.size() * 16);
21459 for (String domain : result) {
21460 if (sb.length() > 0) sb.append(" ");
21463 return sb.toString();
21466 // ------- apps on sdcard specific code -------
21467 static final boolean DEBUG_SD_INSTALL = false;
21469 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21471 private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21473 private boolean mMediaMounted = false;
21475 static String getEncryptKey() {
21477 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21478 SD_ENCRYPTION_KEYSTORE_NAME);
21479 if (sdEncKey == null) {
21480 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21481 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21482 if (sdEncKey == null) {
21483 Slog.e(TAG, "Failed to create encryption keys");
21488 } catch (NoSuchAlgorithmException nsae) {
21489 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21491 } catch (IOException ioe) {
21492 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21497 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21498 ArrayList<AndroidPackage> packages, IIntentReceiver finishedReceiver) {
21499 final int size = packages.size();
21500 final String[] packageNames = new String[size];
21501 final int[] packageUids = new int[size];
21502 for (int i = 0; i < size; i++) {
21503 final AndroidPackage pkg = packages.get(i);
21504 packageNames[i] = pkg.getPackageName();
21505 packageUids[i] = pkg.getUid();
21507 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
21511 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21512 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21513 sendResourcesChangedBroadcast(mediaStatus, replacing,
21514 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
21517 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21518 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21519 int size = pkgList.length;
21521 // Send broadcasts here
21522 Bundle extras = new Bundle();
21523 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
21524 if (uidArr != null) {
21525 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
21528 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
21530 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
21531 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
21532 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null, null);
21536 private void loadPrivatePackages(final VolumeInfo vol) {
21537 mHandler.post(() -> loadPrivatePackagesInner(vol));
21540 private void loadPrivatePackagesInner(VolumeInfo vol) {
21541 final String volumeUuid = vol.fsUuid;
21542 if (TextUtils.isEmpty(volumeUuid)) {
21543 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
21547 final ArrayList<PackageFreezer> freezers = new ArrayList<>();
21548 final ArrayList<AndroidPackage> loaded = new ArrayList<>();
21549 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
21551 final VersionInfo ver;
21552 final List<PackageSetting> packages;
21553 synchronized (mLock) {
21554 ver = mSettings.findOrCreateVersion(volumeUuid);
21555 packages = mSettings.getVolumePackagesLPr(volumeUuid);
21558 for (PackageSetting ps : packages) {
21559 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
21560 synchronized (mInstallLock) {
21561 final AndroidPackage pkg;
21563 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
21566 } catch (PackageManagerException e) {
21567 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
21570 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
21571 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
21572 | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY
21573 | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
21578 // Reconcile app data for all started/unlocked users
21579 final StorageManager sm = mInjector.getStorageManager();
21580 UserManagerInternal umInternal = mInjector.getUserManagerInternal();
21581 for (UserInfo user : mUserManager.getUsers(false /* includeDying */)) {
21583 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21584 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21585 } else if (umInternal.isUserRunning(user.id)) {
21586 flags = StorageManager.FLAG_STORAGE_DE;
21592 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
21593 synchronized (mInstallLock) {
21594 reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
21596 } catch (IllegalStateException e) {
21597 // Device was probably ejected, and we'll process that event momentarily
21598 Slog.w(TAG, "Failed to prepare storage: " + e);
21602 synchronized (mLock) {
21603 final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
21605 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21606 + mSdkVersion + "; regranting permissions for " + volumeUuid);
21608 mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated);
21610 // Yay, everything is now upgraded
21611 ver.forceCurrent();
21613 mSettings.writeLPr();
21616 for (PackageFreezer freezer : freezers) {
21620 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
21621 sendResourcesChangedBroadcast(true, false, loaded, null);
21622 mLoadedVolumes.add(vol.getId());
21625 private void unloadPrivatePackages(final VolumeInfo vol) {
21626 mHandler.post(() -> unloadPrivatePackagesInner(vol));
21629 private void unloadPrivatePackagesInner(VolumeInfo vol) {
21630 final String volumeUuid = vol.fsUuid;
21631 if (TextUtils.isEmpty(volumeUuid)) {
21632 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
21636 final ArrayList<AndroidPackage> unloaded = new ArrayList<>();
21637 synchronized (mInstallLock) {
21638 synchronized (mLock) {
21639 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
21640 for (PackageSetting ps : packages) {
21641 if (ps.pkg == null) continue;
21643 final AndroidPackage pkg = ps.pkg;
21644 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21645 final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
21647 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
21648 "unloadPrivatePackagesInner")) {
21649 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
21653 Slog.w(TAG, "Failed to unload " + ps.codePath);
21657 // Try very hard to release any references to this package
21658 // so we don't risk the system server being killed due to
21660 AttributeCache.instance().removePackage(ps.name);
21663 mSettings.writeLPr();
21667 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
21668 sendResourcesChangedBroadcast(false, false, unloaded, null);
21669 mLoadedVolumes.remove(vol.getId());
21671 // Try very hard to release any references to this path so we don't risk
21672 // the system server being killed due to open FDs
21673 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
21675 for (int i = 0; i < 3; i++) {
21677 System.runFinalization();
21681 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
21682 throws PackageManagerException {
21683 synchronized (mLock) {
21684 // Normalize package name to handle renamed packages
21685 packageName = normalizePackageNameLPr(packageName);
21687 final PackageSetting ps = mSettings.mPackages.get(packageName);
21689 throw new PackageManagerException("Package " + packageName + " is unknown");
21690 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21691 throw new PackageManagerException(
21692 "Package " + packageName + " found on unknown volume " + volumeUuid
21693 + "; expected volume " + ps.volumeUuid);
21694 } else if (!ps.getInstalled(userId)) {
21695 throw new PackageManagerException(
21696 "Package " + packageName + " not installed for user " + userId);
21701 private List<String> collectAbsoluteCodePaths() {
21702 synchronized (mLock) {
21703 List<String> codePaths = new ArrayList<>();
21704 final int packageCount = mSettings.mPackages.size();
21705 for (int i = 0; i < packageCount; i++) {
21706 final PackageSetting ps = mSettings.mPackages.valueAt(i);
21707 codePaths.add(ps.codePath.getAbsolutePath());
21714 * Examine all apps present on given mounted volume, and destroy apps that
21715 * aren't expected, either due to uninstallation or reinstallation on
21718 private void reconcileApps(String volumeUuid) {
21719 List<String> absoluteCodePaths = collectAbsoluteCodePaths();
21720 List<File> filesToDelete = null;
21722 final File[] files = FileUtils.listFilesOrEmpty(
21723 Environment.getDataAppDirectory(volumeUuid));
21724 for (File file : files) {
21725 final boolean isPackage = (isApkFile(file) || file.isDirectory())
21726 && !PackageInstallerService.isStageName(file.getName());
21728 // Ignore entries which are not packages
21732 String absolutePath = file.getAbsolutePath();
21734 boolean pathValid = false;
21735 final int absoluteCodePathCount = absoluteCodePaths.size();
21736 for (int i = 0; i < absoluteCodePathCount; i++) {
21737 String absoluteCodePath = absoluteCodePaths.get(i);
21738 if (absoluteCodePath.startsWith(absolutePath)) {
21745 if (filesToDelete == null) {
21746 filesToDelete = new ArrayList<>();
21748 filesToDelete.add(file);
21752 if (filesToDelete != null) {
21753 final int fileToDeleteCount = filesToDelete.size();
21754 for (int i = 0; i < fileToDeleteCount; i++) {
21755 File fileToDelete = filesToDelete.get(i);
21756 logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
21757 synchronized (mInstallLock) {
21758 removeCodePathLI(fileToDelete);
21765 * Reconcile all app data for the given user.
21767 * Verifies that directories exist and that ownership and labeling is
21768 * correct for all installed apps on all mounted volumes.
21770 void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
21771 final StorageManager storage = mInjector.getStorageManager();
21772 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
21773 final String volumeUuid = vol.getFsUuid();
21774 synchronized (mInstallLock) {
21775 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
21780 @GuardedBy("mInstallLock")
21781 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21782 boolean migrateAppData) {
21783 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
21787 * Reconcile all app data on given mounted volume.
21789 * Destroys app data that isn't expected, either due to uninstallation or
21790 * reinstallation on another volume.
21792 * Verifies that directories exist and that ownership and labeling is
21793 * correct for all installed apps.
21794 * @return list of skipped non-core packages (if {@code onlyCoreApps} is true)
21796 @GuardedBy("mInstallLock")
21797 private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21798 boolean migrateAppData, boolean onlyCoreApps) {
21799 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
21800 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
21801 List<String> result = onlyCoreApps ? new ArrayList<>() : null;
21803 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
21804 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
21806 // First look for stale data that doesn't belong, and check if things
21807 // have changed since we did our last restorecon
21808 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
21809 if (StorageManager.isFileEncryptedNativeOrEmulated()
21810 && !StorageManager.isUserKeyUnlocked(userId)) {
21811 throw new RuntimeException(
21812 "Yikes, someone asked us to reconcile CE storage while " + userId
21813 + " was still locked; this would have caused massive data loss!");
21816 final File[] files = FileUtils.listFilesOrEmpty(ceDir);
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_CE, 0);
21826 } catch (InstallerException e2) {
21827 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21832 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
21833 final File[] files = FileUtils.listFilesOrEmpty(deDir);
21834 for (File file : files) {
21835 final String packageName = file.getName();
21837 assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21838 } catch (PackageManagerException e) {
21839 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21841 mInstaller.destroyAppData(volumeUuid, packageName, userId,
21842 StorageManager.FLAG_STORAGE_DE, 0);
21843 } catch (InstallerException e2) {
21844 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21850 // Ensure that data directories are ready to roll for all packages
21851 // installed for this volume and user
21852 final List<PackageSetting> packages;
21853 synchronized (mLock) {
21854 packages = mSettings.getVolumePackagesLPr(volumeUuid);
21856 int preparedCount = 0;
21857 for (PackageSetting ps : packages) {
21858 final String packageName = ps.name;
21859 if (ps.pkg == null) {
21860 Slog.w(TAG, "Odd, missing scanned package " + packageName);
21861 // TODO: might be due to legacy ASEC apps; we should circle back
21862 // and reconcile again once they're scanned
21865 // Skip non-core apps if requested
21866 if (onlyCoreApps && !ps.pkg.isCoreApp()) {
21867 result.add(packageName);
21871 if (ps.getInstalled(userId)) {
21872 prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
21877 Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
21882 * Prepare app data for the given app just after it was installed or
21883 * upgraded. This method carefully only touches users that it's installed
21884 * for, and it forces a restorecon to handle any seinfo changes.
21886 * Verifies that directories exist and that ownership and labeling is
21887 * correct for all installed apps. If there is an ownership mismatch, it
21888 * will try recovering system apps by wiping data; third-party app data is
21891 * <em>Note: To avoid a deadlock, do not call this method with {@code mLock} lock held</em>
21893 private void prepareAppDataAfterInstallLIF(AndroidPackage pkg) {
21894 final PackageSetting ps;
21895 synchronized (mLock) {
21896 ps = mSettings.mPackages.get(pkg.getPackageName());
21897 mSettings.writeKernelMappingLPr(ps);
21900 UserManagerInternal umInternal = mInjector.getUserManagerInternal();
21901 StorageManagerInternal smInternal = mInjector.getStorageManagerInternal();
21902 for (UserInfo user : mUserManager.getUsers(false /*excludeDying*/)) {
21904 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21905 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21906 } else if (umInternal.isUserRunning(user.id)) {
21907 flags = StorageManager.FLAG_STORAGE_DE;
21912 if (ps.getInstalled(user.id)) {
21913 // TODO: when user data is locked, mark that we're still dirty
21914 prepareAppDataLIF(pkg, user.id, flags);
21916 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21917 // Prepare app data on external storage; currently this is used to
21918 // setup any OBB dirs that were created by the installer correctly.
21919 int uid = UserHandle.getUid(user.id, UserHandle.getAppId(pkg.getUid()));
21920 smInternal.prepareAppDataAfterInstall(pkg.getPackageName(), uid);
21927 * Prepare app data for the given app.
21929 * Verifies that directories exist and that ownership and labeling is
21930 * correct for all installed apps. If there is an ownership mismatch, this
21931 * will try recovering system apps by wiping data; third-party app data is
21934 private void prepareAppDataLIF(AndroidPackage pkg, int userId, int flags) {
21936 Slog.wtf(TAG, "Package was null!", new Throwable());
21939 prepareAppDataLeafLIF(pkg, userId, flags);
21942 private void prepareAppDataAndMigrateLIF(AndroidPackage pkg, int userId, int flags,
21943 boolean maybeMigrateAppData) {
21944 prepareAppDataLIF(pkg, userId, flags);
21946 if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
21947 // We may have just shuffled around app data directories, so
21948 // prepare them one more time
21949 prepareAppDataLIF(pkg, userId, flags);
21953 private void prepareAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
21954 if (DEBUG_APP_DATA) {
21955 Slog.v(TAG, "prepareAppData for " + pkg.getPackageName() + " u" + userId + " 0x"
21956 + Integer.toHexString(flags));
21959 final PackageSetting ps;
21960 synchronized (mLock) {
21961 ps = mSettings.mPackages.get(pkg.getPackageName());
21963 final String volumeUuid = pkg.getVolumeUuid();
21964 final String packageName = pkg.getPackageName();
21966 final int appId = UserHandle.getAppId(pkg.getUid());
21968 String pkgSeInfo = AndroidPackageUtils.getSeInfo(pkg, ps);
21970 Preconditions.checkNotNull(pkgSeInfo);
21972 final String seInfo = pkgSeInfo + (pkg.getSeInfoUser() != null ? pkg.getSeInfoUser() : "");
21973 long ceDataInode = -1;
21975 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21976 appId, seInfo, pkg.getTargetSdkVersion());
21977 } catch (InstallerException e) {
21978 if (pkg.isSystem()) {
21979 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
21980 + ", but trying to recover: " + e);
21981 destroyAppDataLeafLIF(pkg, userId, flags);
21983 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21984 appId, seInfo, pkg.getTargetSdkVersion());
21985 logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
21986 } catch (InstallerException e2) {
21987 logCriticalInfo(Log.DEBUG, "Recovery failed!");
21990 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
21993 // Prepare the application profiles only for upgrades and first boot (so that we don't
21994 // repeat the same operation at each boot).
21995 // We only have to cover the upgrade and first boot here because for app installs we
21996 // prepare the profiles before invoking dexopt (in installPackageLI).
21998 // We also have to cover non system users because we do not call the usual install package
21999 // methods for them.
22001 // NOTE: in order to speed up first boot time we only create the current profile and do not
22002 // update the content of the reference profile. A system image should already be configured
22003 // with the right profile keys and the profiles for the speed-profile prebuilds should
22004 // already be copied. That's done in #performDexOptUpgrade.
22006 // TODO(calin, mathieuc): We should use .dm files for prebuilds profiles instead of
22007 // manually copying them in #performDexOptUpgrade. When we do that we should have a more
22008 // granular check here and only update the existing profiles.
22009 if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) {
22010 mArtManagerService.prepareAppProfiles(pkg, userId,
22011 /* updateReferenceProfileContent= */ false);
22014 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
22015 // TODO: mark this structure as dirty so we persist it!
22016 synchronized (mLock) {
22018 ps.setCeDataInode(ceDataInode, userId);
22023 prepareAppDataContentsLeafLIF(pkg, ps, userId, flags);
22026 private void prepareAppDataContentsLIF(AndroidPackage pkg, @Nullable PackageSetting pkgSetting,
22027 int userId, int flags) {
22029 Slog.wtf(TAG, "Package was null!", new Throwable());
22032 prepareAppDataContentsLeafLIF(pkg, pkgSetting, userId, flags);
22035 private void prepareAppDataContentsLeafLIF(AndroidPackage pkg,
22036 @Nullable PackageSetting pkgSetting, int userId, int flags) {
22037 final String volumeUuid = pkg.getVolumeUuid();
22038 final String packageName = pkg.getPackageName();
22040 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22041 // Create a native library symlink only if we have native libraries
22042 // and if the native libraries are 32 bit libraries. We do not provide
22043 // this symlink for 64 bit libraries.
22044 String primaryCpuAbi = AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting);
22045 if (primaryCpuAbi != null && !VMRuntime.is64BitAbi(primaryCpuAbi)) {
22046 final String nativeLibPath = pkg.getNativeLibraryDir();
22048 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
22049 nativeLibPath, userId);
22050 } catch (InstallerException e) {
22051 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
22058 * For system apps on non-FBE devices, this method migrates any existing
22059 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
22060 * requested by the app.
22062 private boolean maybeMigrateAppDataLIF(AndroidPackage pkg, int userId) {
22063 if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
22064 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
22065 final int storageTarget = pkg.isDefaultToDeviceProtectedStorage()
22066 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
22068 mInstaller.migrateAppData(pkg.getVolumeUuid(), pkg.getPackageName(), userId,
22070 } catch (InstallerException e) {
22071 logCriticalInfo(Log.WARN,
22072 "Failed to migrate " + pkg.getPackageName() + ": " + e.getMessage());
22080 public PackageFreezer freezePackage(String packageName, String killReason) {
22081 return freezePackage(packageName, UserHandle.USER_ALL, killReason);
22084 public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
22085 return new PackageFreezer(packageName, userId, killReason);
22088 public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
22089 String killReason) {
22090 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
22093 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
22094 String killReason) {
22095 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
22096 return new PackageFreezer();
22098 return freezePackage(packageName, userId, killReason);
22102 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
22103 String killReason) {
22104 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
22107 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
22108 String killReason) {
22109 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
22110 return new PackageFreezer();
22112 return freezePackage(packageName, userId, killReason);
22117 * Class that freezes and kills the given package upon creation, and
22118 * unfreezes it upon closing. This is typically used when doing surgery on
22119 * app code/data to prevent the app from running while you're working.
22121 private class PackageFreezer implements AutoCloseable {
22122 private final String mPackageName;
22124 private final boolean mWeFroze;
22126 private final AtomicBoolean mClosed = new AtomicBoolean();
22127 private final CloseGuard mCloseGuard = CloseGuard.get();
22130 * Create and return a stub freezer that doesn't actually do anything,
22131 * typically used when someone requested
22132 * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22133 * {@link PackageManager#DELETE_DONT_KILL_APP}.
22135 public PackageFreezer() {
22136 mPackageName = null;
22138 mCloseGuard.open("close");
22141 public PackageFreezer(String packageName, int userId, String killReason) {
22142 synchronized (mLock) {
22143 mPackageName = packageName;
22144 mWeFroze = mFrozenPackages.add(mPackageName);
22146 final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22148 killApplication(ps.name, ps.appId, userId, killReason);
22151 mCloseGuard.open("close");
22155 protected void finalize() throws Throwable {
22157 mCloseGuard.warnIfOpen();
22165 public void close() {
22166 mCloseGuard.close();
22167 if (mClosed.compareAndSet(false, true)) {
22168 synchronized (mLock) {
22170 mFrozenPackages.remove(mPackageName);
22178 * Verify that given package is currently frozen.
22180 private void checkPackageFrozen(String packageName) {
22181 synchronized (mLock) {
22182 if (!mFrozenPackages.contains(packageName)) {
22183 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
22189 public int movePackage(final String packageName, final String volumeUuid) {
22190 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22192 final int callingUid = Binder.getCallingUid();
22193 final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
22194 final int moveId = mNextMoveId.getAndIncrement();
22195 mHandler.post(() -> {
22197 movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
22198 } catch (PackageManagerException e) {
22199 Slog.w(TAG, "Failed to move " + packageName, e);
22200 mMoveCallbacks.notifyStatusChanged(moveId, e.error);
22206 private void movePackageInternal(final String packageName, final String volumeUuid,
22207 final int moveId, final int callingUid, UserHandle user)
22208 throws PackageManagerException {
22209 final StorageManager storage = mInjector.getStorageManager();
22210 final PackageManager pm = mContext.getPackageManager();
22212 final String currentVolumeUuid;
22213 final File codeFile;
22214 final InstallSource installSource;
22215 final String packageAbiOverride;
22217 final String seinfo;
22218 final String label;
22219 final int targetSdkVersion;
22220 final PackageFreezer freezer;
22221 final int[] installedUserIds;
22222 final boolean isCurrentLocationExternal;
22223 final String fromCodePath;
22226 synchronized (mLock) {
22227 final AndroidPackage pkg = mPackages.get(packageName);
22228 final PackageSetting ps = mSettings.mPackages.get(packageName);
22231 || shouldFilterApplicationLocked(ps, callingUid, user.getIdentifier())) {
22232 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
22234 if (pkg.isSystem()) {
22235 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22236 "Cannot move system application");
22239 final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22240 final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22241 com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22242 if (isInternalStorage && !allow3rdPartyOnInternal) {
22243 throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22244 "3rd party apps are not allowed on internal storage");
22247 currentVolumeUuid = ps.volumeUuid;
22249 final File probe = new File(pkg.getCodePath());
22250 final File probeOat = new File(probe, "oat");
22251 if (!probe.isDirectory() || !probeOat.isDirectory()) {
22252 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22253 "Move only supported for modern cluster style installs");
22256 if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22257 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22258 "Package already moved to " + volumeUuid);
22260 if (!pkg.isExternalStorage() && isPackageDeviceAdminOnAnyUser(packageName)) {
22261 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
22262 "Device admin cannot be moved");
22265 if (mFrozenPackages.contains(packageName)) {
22266 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
22267 "Failed to move already frozen package");
22270 isCurrentLocationExternal = pkg.isExternalStorage();
22271 codeFile = new File(pkg.getCodePath());
22272 installSource = ps.installSource;
22273 packageAbiOverride = ps.cpuAbiOverrideString;
22274 appId = UserHandle.getAppId(pkg.getUid());
22275 seinfo = AndroidPackageUtils.getSeInfo(pkg, ps);
22276 label = String.valueOf(pm.getApplicationLabel(pkg.toAppInfoWithoutState()));
22277 targetSdkVersion = pkg.getTargetSdkVersion();
22278 freezer = freezePackage(packageName, "movePackageInternal");
22279 installedUserIds = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
22280 if (codeFile.getParentFile().getName().startsWith(RANDOM_DIR_PREFIX)) {
22281 fromCodePath = codeFile.getParentFile().getAbsolutePath();
22283 fromCodePath = codeFile.getAbsolutePath();
22287 final Bundle extras = new Bundle();
22288 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
22289 extras.putString(Intent.EXTRA_TITLE, label);
22290 mMoveCallbacks.notifyCreated(moveId, extras);
22293 final boolean moveCompleteApp;
22294 final File measurePath;
22296 installFlags = INSTALL_INTERNAL;
22297 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
22298 moveCompleteApp = true;
22299 measurePath = Environment.getDataAppDirectory(volumeUuid);
22300 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
22301 moveCompleteApp = false;
22302 measurePath = storage.getPrimaryPhysicalVolume().getPath();
22304 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
22305 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
22306 || !volume.isMountedWritable()) {
22308 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22309 "Move location not mounted private volume");
22312 moveCompleteApp = true;
22313 measurePath = Environment.getDataAppDirectory(volumeUuid);
22316 // If we're moving app data around, we need all the users unlocked
22317 if (moveCompleteApp) {
22318 for (int userId : installedUserIds) {
22319 if (StorageManager.isFileEncryptedNativeOrEmulated()
22320 && !StorageManager.isUserKeyUnlocked(userId)) {
22321 throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
22322 "User " + userId + " must be unlocked");
22327 final PackageStats stats = new PackageStats(null, -1);
22328 synchronized (mInstaller) {
22329 for (int userId : installedUserIds) {
22330 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22332 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22333 "Failed to measure package size");
22338 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
22341 final long startFreeBytes = measurePath.getUsableSpace();
22342 final long sizeBytes;
22343 if (moveCompleteApp) {
22344 sizeBytes = stats.codeSize + stats.dataSize;
22346 sizeBytes = stats.codeSize;
22349 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
22351 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22352 "Not enough free space to move");
22355 mMoveCallbacks.notifyStatusChanged(moveId, 10);
22357 final CountDownLatch installedLatch = new CountDownLatch(1);
22358 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
22360 public void onUserActionRequired(Intent intent) throws RemoteException {
22361 throw new IllegalStateException();
22365 public void onPackageInstalled(String basePackageName, int returnCode, String msg,
22366 Bundle extras) throws RemoteException {
22367 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
22368 + PackageManager.installStatusToString(returnCode, msg));
22370 installedLatch.countDown();
22373 final int status = PackageManager.installStatusToPublicStatus(returnCode);
22375 case PackageInstaller.STATUS_SUCCESS:
22376 mMoveCallbacks.notifyStatusChanged(moveId,
22377 PackageManager.MOVE_SUCCEEDED);
22378 logAppMovedStorage(packageName, isCurrentLocationExternal);
22380 case PackageInstaller.STATUS_FAILURE_STORAGE:
22381 mMoveCallbacks.notifyStatusChanged(moveId,
22382 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
22385 mMoveCallbacks.notifyStatusChanged(moveId,
22386 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22392 final MoveInfo move;
22393 if (moveCompleteApp) {
22394 // Kick off a thread to report progress estimates
22398 if (installedLatch.await(1, TimeUnit.SECONDS)) {
22401 } catch (InterruptedException ignored) {
22404 final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
22405 final int progress = 10 + (int) MathUtils.constrain(
22406 ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
22407 mMoveCallbacks.notifyStatusChanged(moveId, progress);
22411 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
22412 appId, seinfo, targetSdkVersion, fromCodePath);
22417 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
22419 final Message msg = mHandler.obtainMessage(INIT_COPY);
22420 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
22421 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
22422 installSource, volumeUuid, null /*verificationInfo*/, user,
22423 packageAbiOverride, null /*grantedPermissions*/,
22424 null /*whitelistedRestrictedPermissions*/, PackageParser.SigningDetails.UNKNOWN,
22425 PackageManager.INSTALL_REASON_UNKNOWN, PackageManager.VERSION_CODE_HIGHEST,
22426 DataLoaderType.NONE);
22427 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
22430 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
22431 System.identityHashCode(msg.obj));
22432 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
22433 System.identityHashCode(msg.obj));
22435 mHandler.sendMessage(msg);
22439 * Logs that an app has been moved from internal to external storage and vice versa.
22440 * @param packageName The package that was moved.
22442 private void logAppMovedStorage(String packageName, boolean isPreviousLocationExternal) {
22443 final AndroidPackage pkg;
22444 synchronized (mLock) {
22445 pkg = mPackages.get(packageName);
22451 final StorageManager storage = mInjector.getStorageManager();;
22452 VolumeInfo volume = storage.findVolumeByUuid(pkg.getStorageUuid().toString());
22453 int packageExternalStorageType = getPackageExternalStorageType(volume, pkg.isExternalStorage());
22455 if (!isPreviousLocationExternal && pkg.isExternalStorage()) {
22456 // Move from internal to external storage.
22457 FrameworkStatsLog.write(FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED,
22458 packageExternalStorageType,
22459 FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_EXTERNAL,
22461 } else if (isPreviousLocationExternal && !pkg.isExternalStorage()) {
22462 // Move from external to internal storage.
22463 FrameworkStatsLog.write(FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED,
22464 packageExternalStorageType,
22465 FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_INTERNAL,
22471 public int movePrimaryStorage(String volumeUuid) throws RemoteException {
22472 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22474 final int realMoveId = mNextMoveId.getAndIncrement();
22475 final Bundle extras = new Bundle();
22476 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
22477 mMoveCallbacks.notifyCreated(realMoveId, extras);
22479 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
22481 public void onCreated(int moveId, Bundle extras) {
22486 public void onStatusChanged(int moveId, int status, long estMillis) {
22487 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
22491 final StorageManager storage = mInjector.getStorageManager();
22492 storage.setPrimaryStorageUuid(volumeUuid, callback);
22497 public int getMoveStatus(int moveId) {
22498 mContext.enforceCallingOrSelfPermission(
22499 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22500 return mMoveCallbacks.mLastStatus.get(moveId);
22504 public void registerMoveCallback(IPackageMoveObserver callback) {
22505 mContext.enforceCallingOrSelfPermission(
22506 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22507 mMoveCallbacks.register(callback);
22511 public void unregisterMoveCallback(IPackageMoveObserver callback) {
22512 mContext.enforceCallingOrSelfPermission(
22513 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22514 mMoveCallbacks.unregister(callback);
22518 public boolean setInstallLocation(int loc) {
22519 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
22521 if (getInstallLocation() == loc) {
22524 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
22525 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
22526 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
22527 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
22534 public int getInstallLocation() {
22535 // allow instant app access
22536 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
22537 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
22538 PackageHelper.APP_INSTALL_AUTO);
22541 /** Called by UserManagerService */
22542 void cleanUpUser(UserManagerService userManager, @UserIdInt int userId) {
22543 synchronized (mLock) {
22544 mDirtyUsers.remove(userId);
22545 mUserNeedsBadging.delete(userId);
22546 mSettings.removeUserLPw(userId);
22547 mPendingBroadcasts.remove(userId);
22548 mInstantAppRegistry.onUserRemovedLPw(userId);
22549 removeUnusedPackagesLPw(userManager, userId);
22554 * We're removing userId and would like to remove any downloaded packages
22555 * that are no longer in use by any other user.
22556 * @param userId the user being removed
22558 @GuardedBy("mLock")
22559 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userId) {
22560 final boolean DEBUG_CLEAN_APKS = false;
22561 int [] users = userManager.getUserIds();
22562 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
22563 while (psit.hasNext()) {
22564 PackageSetting ps = psit.next();
22565 if (ps.pkg == null) {
22568 final String packageName = ps.pkg.getPackageName();
22569 // Skip over if system app or static shared library
22570 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0
22571 || !TextUtils.isEmpty(ps.pkg.getStaticSharedLibName())) {
22574 if (DEBUG_CLEAN_APKS) {
22575 Slog.i(TAG, "Checking package " + packageName);
22577 boolean keep = shouldKeepUninstalledPackageLPr(packageName);
22579 if (DEBUG_CLEAN_APKS) {
22580 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO");
22583 for (int i = 0; i < users.length; i++) {
22584 if (users[i] != userId && ps.getInstalled(users[i])) {
22586 if (DEBUG_CLEAN_APKS) {
22587 Slog.i(TAG, " Keeping package " + packageName + " for user "
22595 if (DEBUG_CLEAN_APKS) {
22596 Slog.i(TAG, " Removing package " + packageName);
22599 mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22606 * Called by UserManagerService.
22608 * @param installablePackages system packages that should be initially installed for this user,
22609 * or {@code null} if all system packages should be installed
22610 * @param disallowedPackages packages that should not be initially installed. Takes precedence
22611 * over installablePackages.
22613 void createNewUser(int userId, @Nullable Set<String> installablePackages,
22614 String[] disallowedPackages) {
22615 synchronized (mInstallLock) {
22616 mSettings.createNewUserLI(this, mInstaller, userId,
22617 installablePackages, disallowedPackages);
22619 synchronized (mLock) {
22620 scheduleWritePackageRestrictionsLocked(userId);
22621 scheduleWritePackageListLocked(userId);
22622 primeDomainVerificationsLPw(userId);
22626 void onNewUserCreated(final int userId) {
22627 mPermissionManager.onNewUserCreated(userId);
22630 boolean readPermissionStateForUser(@UserIdInt int userId) {
22631 synchronized (mPackages) {
22632 mSettings.readPermissionStateForUserSyncLPr(userId);
22633 return mSettings.areDefaultRuntimePermissionsGrantedLPr(userId);
22638 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
22639 mContext.enforceCallingOrSelfPermission(
22640 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
22641 "Only package verification agents can read the verifier device identity");
22643 synchronized (mLock) {
22644 return mSettings.getVerifierDeviceIdentityLPw();
22649 public boolean isStorageLow() {
22650 // allow instant applications
22651 final long token = Binder.clearCallingIdentity();
22653 final DeviceStorageMonitorInternal
22654 dsm = mInjector.getDeviceStorageMonitorInternal();
22656 return dsm.isMemoryLow();
22661 Binder.restoreCallingIdentity(token);
22666 public IPackageInstaller getPackageInstaller() {
22667 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
22670 return mInstallerService;
22674 public IArtManager getArtManager() {
22675 return mArtManagerService;
22678 private boolean userNeedsBadging(int userId) {
22679 int index = mUserNeedsBadging.indexOfKey(userId);
22681 final UserInfo userInfo;
22682 final long token = Binder.clearCallingIdentity();
22684 userInfo = mUserManager.getUserInfo(userId);
22686 Binder.restoreCallingIdentity(token);
22689 if (userInfo != null && userInfo.isManagedProfile()) {
22694 mUserNeedsBadging.put(userId, b);
22697 return mUserNeedsBadging.valueAt(index);
22701 public KeySet getKeySetByAlias(String packageName, String alias) {
22702 if (packageName == null || alias == null) {
22705 synchronized(mLock) {
22706 final AndroidPackage pkg = mPackages.get(packageName);
22708 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22709 throw new IllegalArgumentException("Unknown package: " + packageName);
22711 final PackageSetting ps = getPackageSetting(pkg.getPackageName());
22712 if (shouldFilterApplicationLocked(
22713 ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
22714 Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
22715 throw new IllegalArgumentException("Unknown package: " + packageName);
22717 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22718 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
22723 public KeySet getSigningKeySet(String packageName) {
22724 if (packageName == null) {
22727 synchronized (mLock) {
22728 final int callingUid = Binder.getCallingUid();
22729 final int callingUserId = UserHandle.getUserId(callingUid);
22730 final AndroidPackage pkg = mPackages.get(packageName);
22732 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22733 throw new IllegalArgumentException("Unknown package: " + packageName);
22735 final PackageSetting ps = getPackageSetting(pkg.getPackageName());
22736 if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
22737 // filter and pretend the package doesn't exist
22738 Slog.w(TAG, "KeySet requested for filtered package: " + packageName
22739 + ", uid:" + callingUid);
22740 throw new IllegalArgumentException("Unknown package: " + packageName);
22742 if (pkg.getUid() != callingUid
22743 && Process.SYSTEM_UID != callingUid) {
22744 throw new SecurityException("May not access signing KeySet of other apps.");
22746 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22747 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
22752 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
22753 final int callingUid = Binder.getCallingUid();
22754 if (getInstantAppPackageName(callingUid) != null) {
22757 if (packageName == null || ks == null) {
22760 synchronized(mLock) {
22761 final AndroidPackage pkg = mPackages.get(packageName);
22763 || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
22764 callingUid, UserHandle.getUserId(callingUid))) {
22765 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22766 throw new IllegalArgumentException("Unknown package: " + packageName);
22768 IBinder ksh = ks.getToken();
22769 if (ksh instanceof KeySetHandle) {
22770 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22771 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
22778 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
22779 final int callingUid = Binder.getCallingUid();
22780 if (getInstantAppPackageName(callingUid) != null) {
22783 if (packageName == null || ks == null) {
22786 synchronized (mLock) {
22787 final AndroidPackage pkg = mPackages.get(packageName);
22789 || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
22790 callingUid, UserHandle.getUserId(callingUid))) {
22791 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22792 throw new IllegalArgumentException("Unknown package: " + packageName);
22794 IBinder ksh = ks.getToken();
22795 if (ksh instanceof KeySetHandle) {
22796 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22797 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
22803 @GuardedBy("mLock")
22804 private void deletePackageIfUnusedLPr(final String packageName) {
22805 PackageSetting ps = mSettings.mPackages.get(packageName);
22809 if (!ps.isAnyInstalled(mUserManager.getUserIds())) {
22810 // TODO Implement atomic delete if package is unused
22811 // It is currently possible that the package will be deleted even if it is installed
22812 // after this method returns.
22813 mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22814 0, PackageManager.DELETE_ALL_USERS));
22819 * Check and throw if the given before/after packages would be considered a
22822 private static void checkDowngrade(AndroidPackage before, PackageInfoLite after)
22823 throws PackageManagerException {
22824 if (after.getLongVersionCode() < before.getLongVersionCode()) {
22825 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22826 "Update version code " + after.versionCode + " is older than current "
22827 + before.getLongVersionCode());
22828 } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
22829 if (after.baseRevisionCode < before.getBaseRevisionCode()) {
22830 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22831 "Update base revision code " + after.baseRevisionCode
22832 + " is older than current " + before.getBaseRevisionCode());
22835 if (!ArrayUtils.isEmpty(after.splitNames)) {
22836 for (int i = 0; i < after.splitNames.length; i++) {
22837 final String splitName = after.splitNames[i];
22838 final int j = ArrayUtils.indexOf(before.getSplitNames(), splitName);
22840 if (after.splitRevisionCodes[i] < before.getSplitRevisionCodes()[j]) {
22841 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22842 "Update split " + splitName + " revision code "
22843 + after.splitRevisionCodes[i] + " is older than current "
22844 + before.getSplitRevisionCodes()[j]);
22852 private static class MoveCallbacks extends Handler {
22853 private static final int MSG_CREATED = 1;
22854 private static final int MSG_STATUS_CHANGED = 2;
22856 private final RemoteCallbackList<IPackageMoveObserver>
22857 mCallbacks = new RemoteCallbackList<>();
22859 private final SparseIntArray mLastStatus = new SparseIntArray();
22861 public MoveCallbacks(Looper looper) {
22865 public void register(IPackageMoveObserver callback) {
22866 mCallbacks.register(callback);
22869 public void unregister(IPackageMoveObserver callback) {
22870 mCallbacks.unregister(callback);
22874 public void handleMessage(Message msg) {
22875 final SomeArgs args = (SomeArgs) msg.obj;
22876 final int n = mCallbacks.beginBroadcast();
22877 for (int i = 0; i < n; i++) {
22878 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
22880 invokeCallback(callback, msg.what, args);
22881 } catch (RemoteException ignored) {
22884 mCallbacks.finishBroadcast();
22888 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
22889 throws RemoteException {
22891 case MSG_CREATED: {
22892 callback.onCreated(args.argi1, (Bundle) args.arg2);
22895 case MSG_STATUS_CHANGED: {
22896 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
22902 private void notifyCreated(int moveId, Bundle extras) {
22903 Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
22905 final SomeArgs args = SomeArgs.obtain();
22906 args.argi1 = moveId;
22907 args.arg2 = extras;
22908 obtainMessage(MSG_CREATED, args).sendToTarget();
22911 private void notifyStatusChanged(int moveId, int status) {
22912 notifyStatusChanged(moveId, status, -1);
22915 private void notifyStatusChanged(int moveId, int status, long estMillis) {
22916 Slog.v(TAG, "Move " + moveId + " status " + status);
22918 final SomeArgs args = SomeArgs.obtain();
22919 args.argi1 = moveId;
22920 args.argi2 = status;
22921 args.arg3 = estMillis;
22922 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
22924 synchronized (mLastStatus) {
22925 mLastStatus.put(moveId, status);
22930 private class PackageManagerNative extends IPackageManagerNative.Stub {
22932 public String[] getAllPackages() {
22933 return PackageManagerService.this.getAllPackages().toArray(new String[0]);
22937 public String[] getNamesForUids(int[] uids) throws RemoteException {
22938 final String[] results = PackageManagerService.this.getNamesForUids(uids);
22939 // massage results so they can be parsed by the native binder
22940 for (int i = results.length - 1; i >= 0; --i) {
22941 if (results[i] == null) {
22948 // NB: this differentiates between preloads and sideloads
22950 public String getInstallerForPackage(String packageName) throws RemoteException {
22951 final String installerName = getInstallerPackageName(packageName);
22952 if (!TextUtils.isEmpty(installerName)) {
22953 return installerName;
22955 // differentiate between preload and sideload
22956 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22957 ApplicationInfo appInfo = getApplicationInfo(packageName,
22959 /*userId*/ callingUser);
22960 if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22967 public long getVersionCodeForPackage(String packageName) throws RemoteException {
22969 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22970 PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
22971 if (pInfo != null) {
22972 return pInfo.getLongVersionCode();
22974 } catch (Exception e) {
22980 public int getTargetSdkVersionForPackage(String packageName)
22981 throws RemoteException {
22982 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22983 ApplicationInfo info = getApplicationInfo(packageName, 0, callingUser);
22984 if (info == null) {
22985 throw new RemoteException(
22986 "Couldn't get ApplicationInfo for package " + packageName);
22988 return info.targetSdkVersion;
22992 public boolean[] isAudioPlaybackCaptureAllowed(String[] packageNames)
22993 throws RemoteException {
22994 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22995 boolean[] results = new boolean[packageNames.length];
22996 for (int i = results.length - 1; i >= 0; --i) {
22997 ApplicationInfo appInfo = getApplicationInfo(packageNames[i], 0, callingUser);
22998 results[i] = appInfo == null ? false : appInfo.isAudioPlaybackCaptureAllowed();
23004 public int getLocationFlags(String packageName) throws RemoteException {
23005 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
23006 ApplicationInfo appInfo = getApplicationInfo(packageName,
23008 /*userId*/ callingUser);
23009 if (appInfo == null) {
23010 throw new RemoteException(
23011 "Couldn't get ApplicationInfo for package " + packageName);
23013 return ((appInfo.isSystemApp() ? IPackageManagerNative.LOCATION_SYSTEM : 0)
23014 | (appInfo.isVendor() ? IPackageManagerNative.LOCATION_VENDOR : 0)
23015 | (appInfo.isProduct() ? IPackageManagerNative.LOCATION_PRODUCT : 0));
23019 public String getModuleMetadataPackageName() throws RemoteException {
23020 return PackageManagerService.this.mModuleInfoProvider.getPackageName();
23024 private class PackageManagerInternalImpl extends PackageManagerInternal {
23026 public List<ApplicationInfo> getInstalledApplications(int flags, int userId,
23028 return PackageManagerService.this.getInstalledApplicationsListInternal(flags, userId,
23034 public boolean isPlatformSigned(String packageName) {
23035 PackageSetting packageSetting = mSettings.mPackages.get(packageName);
23036 if (packageSetting == null) {
23039 AndroidPackage pkg = packageSetting.pkg;
23041 // May happen if package in on a removable sd card
23044 return pkg.getSigningDetails().hasAncestorOrSelf(mPlatformPackage.getSigningDetails())
23045 || mPlatformPackage.getSigningDetails().checkCapability(pkg.getSigningDetails(),
23046 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
23050 public boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName) {
23051 SigningDetails sd = getSigningDetails(packageName);
23055 return sd.hasSha256Certificate(restoringFromSigHash,
23056 SigningDetails.CertCapabilities.INSTALLED_DATA);
23060 public boolean isDataRestoreSafe(Signature restoringFromSig, String packageName) {
23061 SigningDetails sd = getSigningDetails(packageName);
23065 return sd.hasCertificate(restoringFromSig,
23066 SigningDetails.CertCapabilities.INSTALLED_DATA);
23070 public boolean hasSignatureCapability(int serverUid, int clientUid,
23071 @SigningDetails.CertCapabilities int capability) {
23072 SigningDetails serverSigningDetails = getSigningDetails(serverUid);
23073 SigningDetails clientSigningDetails = getSigningDetails(clientUid);
23074 return serverSigningDetails.checkCapability(clientSigningDetails, capability)
23075 || clientSigningDetails.hasAncestorOrSelf(serverSigningDetails);
23079 private SigningDetails getSigningDetails(@NonNull String packageName) {
23080 synchronized (mLock) {
23081 AndroidPackage p = mPackages.get(packageName);
23085 return p.getSigningDetails();
23089 private SigningDetails getSigningDetails(int uid) {
23090 synchronized (mLock) {
23091 final int appId = UserHandle.getAppId(uid);
23092 final Object obj = mSettings.getSettingLPr(appId);
23094 if (obj instanceof SharedUserSetting) {
23095 return ((SharedUserSetting) obj).signatures.mSigningDetails;
23096 } else if (obj instanceof PackageSetting) {
23097 final PackageSetting ps = (PackageSetting) obj;
23098 return ps.signatures.mSigningDetails;
23101 return SigningDetails.UNKNOWN;
23106 public boolean isInstantApp(String packageName, int userId) {
23107 return PackageManagerService.this.isInstantApp(packageName, userId);
23111 public String getInstantAppPackageName(int uid) {
23112 return PackageManagerService.this.getInstantAppPackageName(uid);
23116 public boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
23117 synchronized (mLock) {
23118 PackageSetting ps = getPackageSetting(pkg.getPackageName());
23119 return PackageManagerService.this.shouldFilterApplicationLocked(ps, callingUid,
23125 public boolean filterAppAccess(String packageName, int callingUid, int userId) {
23126 synchronized (mLock) {
23127 PackageSetting ps = getPackageSetting(packageName);
23128 return PackageManagerService.this.shouldFilterApplicationLocked(ps, callingUid,
23134 public AndroidPackage getPackage(String packageName) {
23135 synchronized (mLock) {
23136 packageName = resolveInternalPackageNameLPr(
23137 packageName, PackageManager.VERSION_CODE_HIGHEST);
23138 return mPackages.get(packageName);
23143 public AndroidPackage getPackage(int uid) {
23144 synchronized (mLock) {
23145 final String[] packageNames = getPackagesForUidInternal(uid, Process.SYSTEM_UID);
23146 AndroidPackage pkg = null;
23147 final int numPackages = packageNames == null ? 0 : packageNames.length;
23148 for (int i = 0; pkg == null && i < numPackages; i++) {
23149 pkg = mPackages.get(packageNames[i]);
23157 public PackageSetting getPackageSetting(String packageName) {
23158 return PackageManagerService.this.getPackageSetting(packageName);
23162 public PackageList getPackageList(PackageListObserver observer) {
23163 synchronized (mLock) {
23164 final int N = mPackages.size();
23165 final ArrayList<String> list = new ArrayList<>(N);
23166 for (int i = 0; i < N; i++) {
23167 list.add(mPackages.keyAt(i));
23169 final PackageList packageList = new PackageList(list, observer);
23170 if (observer != null) {
23171 mPackageListObservers.add(packageList);
23173 return packageList;
23178 public void removePackageListObserver(PackageListObserver observer) {
23179 synchronized (mLock) {
23180 mPackageListObservers.remove(observer);
23185 public PackageSetting getDisabledSystemPackage(@NonNull String packageName) {
23186 synchronized (mLock) {
23187 return mSettings.getDisabledSystemPkgLPr(packageName);
23193 String getDisabledSystemPackageName(@NonNull String packageName) {
23194 PackageSetting disabledPkgSetting = (PackageSetting) getDisabledSystemPackage(
23196 AndroidPackage disabledPkg = disabledPkgSetting == null ? null : disabledPkgSetting.pkg;
23197 return disabledPkg == null ? null : disabledPkg.getPackageName();
23201 * Only keep package names that refer to {@link PackageParser.Package#isSystem system}
23204 * @param pkgNames The packages to filter
23206 * @return The filtered packages
23208 private @NonNull String[] filterOnlySystemPackages(@Nullable String... pkgNames) {
23209 if (pkgNames == null) {
23210 return ArrayUtils.emptyArray(String.class);
23213 ArrayList<String> systemPackageNames = new ArrayList<>(pkgNames.length);
23215 for (String pkgName: pkgNames) {
23216 synchronized (mLock) {
23217 if (pkgName == null) {
23221 AndroidPackage pkg = getPackage(pkgName);
23223 Log.w(TAG, "Could not find package " + pkgName);
23227 if (!pkg.isSystem()) {
23228 Log.w(TAG, pkgName + " is not system");
23232 systemPackageNames.add(pkgName);
23236 return systemPackageNames.toArray(new String[]{});
23240 public @NonNull String[] getKnownPackageNames(int knownPackage, int userId) {
23241 return dropNonSystemPackages(getKnownPackageNamesInternal(knownPackage, userId));
23244 private String[] getKnownPackageNamesInternal(int knownPackage, int userId) {
23245 switch (knownPackage) {
23246 case PackageManagerInternal.PACKAGE_BROWSER:
23247 return new String[]{mPermissionManager.getDefaultBrowser(userId)};
23248 case PackageManagerInternal.PACKAGE_INSTALLER:
23249 return filterOnlySystemPackages(mRequiredInstallerPackage);
23250 case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
23251 return filterOnlySystemPackages(mSetupWizardPackage);
23252 case PackageManagerInternal.PACKAGE_SYSTEM:
23253 return new String[]{"android"};
23254 case PackageManagerInternal.PACKAGE_VERIFIER:
23255 return filterOnlySystemPackages(mRequiredVerifierPackage);
23256 case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER:
23257 return filterOnlySystemPackages(
23258 mDefaultTextClassifierPackage, mSystemTextClassifierPackageName);
23259 case PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER:
23260 return filterOnlySystemPackages(mRequiredPermissionControllerPackage);
23261 case PackageManagerInternal.PACKAGE_WELLBEING:
23262 return filterOnlySystemPackages(mWellbeingPackage);
23263 case PackageManagerInternal.PACKAGE_DOCUMENTER:
23264 return filterOnlySystemPackages(mDocumenterPackage);
23265 case PackageManagerInternal.PACKAGE_CONFIGURATOR:
23266 return filterOnlySystemPackages(mConfiguratorPackage);
23267 case PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER:
23268 return filterOnlySystemPackages(mIncidentReportApproverPackage);
23269 case PackageManagerInternal.PACKAGE_APP_PREDICTOR:
23270 return filterOnlySystemPackages(mAppPredictionServicePackage);
23271 case PackageManagerInternal.PACKAGE_TELEPHONY:
23272 return filterOnlySystemPackages(mTelephonyPackages);
23273 case PackageManagerInternal.PACKAGE_COMPANION:
23274 return filterOnlySystemPackages("com.android.companiondevicemanager");
23275 case PackageManagerInternal.PACKAGE_RETAIL_DEMO:
23276 return TextUtils.isEmpty(mRetailDemoPackage)
23277 ? ArrayUtils.emptyArray(String.class)
23278 : new String[] {mRetailDemoPackage};
23280 return ArrayUtils.emptyArray(String.class);
23285 public boolean isResolveActivityComponent(ComponentInfo component) {
23286 return mResolveActivity.packageName.equals(component.packageName)
23287 && mResolveActivity.name.equals(component.name);
23291 public void setKeepUninstalledPackages(final List<String> packageList) {
23292 Preconditions.checkNotNull(packageList);
23293 List<String> removedFromList = null;
23294 synchronized (mLock) {
23295 if (mKeepUninstalledPackages != null) {
23296 final int packagesCount = mKeepUninstalledPackages.size();
23297 for (int i = 0; i < packagesCount; i++) {
23298 String oldPackage = mKeepUninstalledPackages.get(i);
23299 if (packageList != null && packageList.contains(oldPackage)) {
23302 if (removedFromList == null) {
23303 removedFromList = new ArrayList<>();
23305 removedFromList.add(oldPackage);
23308 mKeepUninstalledPackages = new ArrayList<>(packageList);
23309 if (removedFromList != null) {
23310 final int removedCount = removedFromList.size();
23311 for (int i = 0; i < removedCount; i++) {
23312 deletePackageIfUnusedLPr(removedFromList.get(i));
23319 public boolean isPermissionsReviewRequired(String packageName, int userId) {
23320 synchronized (mLock) {
23321 final AndroidPackage pkg = mPackages.get(packageName);
23326 return mPermissionManager.isPermissionsReviewRequired(pkg, userId);
23331 public PackageInfo getPackageInfo(
23332 String packageName, int flags, int filterCallingUid, int userId) {
23333 return PackageManagerService.this
23334 .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
23335 flags, filterCallingUid, userId);
23339 public long getCeDataInode(String packageName, int userId) {
23340 synchronized (mLock) {
23341 final PackageSetting ps = mSettings.mPackages.get(packageName);
23343 return ps.getCeDataInode(userId);
23350 public Bundle getSuspendedPackageLauncherExtras(String packageName, int userId) {
23351 synchronized (mLock) {
23352 final PackageSetting ps = mSettings.mPackages.get(packageName);
23353 final Bundle allExtras = new Bundle();
23355 final PackageUserState pus = ps.readUserState(userId);
23356 if (pus.suspended) {
23357 for (int i = 0; i < pus.suspendParams.size(); i++) {
23358 final PackageUserState.SuspendParams params =
23359 pus.suspendParams.valueAt(i);
23360 if (params != null && params.launcherExtras != null) {
23361 allExtras.putAll(params.launcherExtras);
23367 return (allExtras.size() > 0) ? allExtras : null;
23372 public boolean isPackageSuspended(String packageName, int userId) {
23373 synchronized (mLock) {
23374 final PackageSetting ps = mSettings.mPackages.get(packageName);
23375 return (ps != null) ? ps.getSuspended(userId) : false;
23380 public void removeAllNonSystemPackageSuspensions(int userId) {
23381 final String[] allPackages;
23382 synchronized (mLock) {
23383 allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
23385 PackageManagerService.this.removeSuspensionsBySuspendingPackage(allPackages,
23386 (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
23391 public void removeNonSystemPackageSuspensions(String packageName, int userId) {
23392 PackageManagerService.this.removeSuspensionsBySuspendingPackage(
23393 new String[]{packageName},
23394 (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
23399 public void flushPackageRestrictions(int userId) {
23400 synchronized (mLock) {
23401 PackageManagerService.this.flushPackageRestrictionsAsUserInternalLocked(userId);
23406 public void removeDistractingPackageRestrictions(String packageName, int userId) {
23407 PackageManagerService.this.removeDistractingPackageRestrictions(
23408 new String[]{packageName}, userId);
23412 public void removeAllDistractingPackageRestrictions(int userId) {
23413 PackageManagerService.this.removeAllDistractingPackageRestrictions(userId);
23417 public String getSuspendingPackage(String suspendedPackage, int userId) {
23418 synchronized (mLock) {
23419 final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
23421 final PackageUserState pus = ps.readUserState(userId);
23422 if (pus.suspended) {
23423 String suspendingPackage = null;
23424 for (int i = 0; i < pus.suspendParams.size(); i++) {
23425 suspendingPackage = pus.suspendParams.keyAt(i);
23426 if (PLATFORM_PACKAGE_NAME.equals(suspendingPackage)) {
23427 return suspendingPackage;
23430 return suspendingPackage;
23438 public SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage,
23439 String suspendingPackage, int userId) {
23440 synchronized (mLock) {
23441 final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
23443 final PackageUserState pus = ps.readUserState(userId);
23444 if (pus.suspended) {
23445 final PackageUserState.SuspendParams suspendParams =
23446 pus.suspendParams.get(suspendingPackage);
23447 return (suspendParams != null) ? suspendParams.dialogInfo : null;
23455 public int getDistractingPackageRestrictions(String packageName, int userId) {
23456 synchronized (mLock) {
23457 final PackageSetting ps = mSettings.mPackages.get(packageName);
23458 return (ps != null) ? ps.getDistractionFlags(userId) : RESTRICTION_NONE;
23463 public int getPackageUid(String packageName, int flags, int userId) {
23464 return PackageManagerService.this
23465 .getPackageUid(packageName, flags, userId);
23469 public int getPackageUidInternal(String packageName, int flags, int userId) {
23470 return PackageManagerService.this
23471 .getPackageUidInternal(packageName, flags, userId, Process.SYSTEM_UID);
23475 public ApplicationInfo getApplicationInfo(
23476 String packageName, int flags, int filterCallingUid, int userId) {
23477 return PackageManagerService.this
23478 .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
23482 public ActivityInfo getActivityInfo(
23483 ComponentName component, int flags, int filterCallingUid, int userId) {
23484 return PackageManagerService.this
23485 .getActivityInfoInternal(component, flags, filterCallingUid, userId);
23489 public List<ResolveInfo> queryIntentActivities(
23490 Intent intent, String resolvedType, int flags, int filterCallingUid, int userId) {
23491 return PackageManagerService.this
23492 .queryIntentActivitiesInternal(intent, resolvedType, flags, 0, filterCallingUid,
23493 userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
23497 public List<ResolveInfo> queryIntentServices(
23498 Intent intent, int flags, int callingUid, int userId) {
23499 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23500 return PackageManagerService.this
23501 .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
23506 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23508 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
23512 public ComponentName getDefaultHomeActivity(int userId) {
23513 return PackageManagerService.this.getDefaultHomeActivity(userId);
23517 public ComponentName getSystemUiServiceComponent() {
23518 return ComponentName.unflattenFromString(mContext.getResources().getString(
23519 com.android.internal.R.string.config_systemUIServiceComponent));
23523 public void setDeviceAndProfileOwnerPackages(
23524 int deviceOwnerUserId, String deviceOwnerPackage,
23525 SparseArray<String> profileOwnerPackages) {
23526 mProtectedPackages.setDeviceAndProfileOwnerPackages(
23527 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
23529 final ArraySet<Integer> usersWithPoOrDo = new ArraySet<>();
23530 if (deviceOwnerPackage != null) {
23531 usersWithPoOrDo.add(deviceOwnerUserId);
23533 final int sz = profileOwnerPackages.size();
23534 for (int i = 0; i < sz; i++) {
23535 if (profileOwnerPackages.valueAt(i) != null) {
23536 usersWithPoOrDo.add(profileOwnerPackages.keyAt(i));
23542 public void setDeviceOwnerProtectedPackages(List<String> packageNames) {
23543 mProtectedPackages.setDeviceOwnerProtectedPackages(packageNames);
23547 public boolean isPackageDataProtected(int userId, String packageName) {
23548 return mProtectedPackages.isPackageDataProtected(userId, packageName);
23552 public boolean isPackageStateProtected(String packageName, int userId) {
23553 return mProtectedPackages.isPackageStateProtected(userId, packageName);
23557 public boolean isPackageEphemeral(int userId, String packageName) {
23558 synchronized (mLock) {
23559 final PackageSetting ps = mSettings.mPackages.get(packageName);
23560 return ps != null ? ps.getInstantApp(userId) : false;
23565 public boolean wasPackageEverLaunched(String packageName, int userId) {
23566 synchronized (mLock) {
23567 return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23572 public boolean isEnabledAndMatches(ParsedMainComponent component, int flags, int userId) {
23573 synchronized (mLock) {
23574 AndroidPackage pkg = getPackage(component.getPackageName());
23575 return mSettings.isEnabledAndMatchLPr(pkg, component, flags, userId);
23580 public boolean userNeedsBadging(int userId) {
23581 synchronized (mLock) {
23582 return PackageManagerService.this.userNeedsBadging(userId);
23587 public String getNameForUid(int uid) {
23588 return PackageManagerService.this.getNameForUid(uid);
23592 public boolean setInstalled(AndroidPackage pkg, @UserIdInt int userId,
23593 boolean installed) {
23594 synchronized (mLock) {
23595 final PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
23596 if (ps.getInstalled(userId) != installed) {
23597 ps.setInstalled(installed, userId);
23605 public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23606 Intent origIntent, String resolvedType, String callingPackage,
23607 @Nullable String callingFeatureId, boolean isRequesterInstantApp,
23608 Bundle verificationBundle, int userId) {
23609 PackageManagerService.this.requestInstantAppResolutionPhaseTwo(responseObj, origIntent,
23610 resolvedType, callingPackage, callingFeatureId, isRequesterInstantApp,
23611 verificationBundle, userId);
23615 public void grantImplicitAccess(int userId, Intent intent,
23616 int recipientAppId, int visibleUid, boolean direct) {
23617 synchronized (mLock) {
23618 final AndroidPackage visiblePackage = getPackage(visibleUid);
23619 final int recipientUid = UserHandle.getUid(userId, recipientAppId);
23620 if (visiblePackage == null || getPackage(recipientUid) == null) {
23624 final boolean instantApp =
23625 isInstantAppInternal(visiblePackage.getPackageName(), userId, visibleUid);
23628 // if the interaction that lead to this granting access to an instant app
23629 // was indirect (i.e.: URI permission grant), do not actually execute the
23633 mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23634 recipientAppId, UserHandle.getAppId(visibleUid) /*instantAppId*/);
23636 mAppsFilter.grantImplicitAccess(recipientUid, visibleUid);
23642 public boolean isInstantAppInstallerComponent(ComponentName component) {
23643 synchronized (mLock) {
23644 return mInstantAppInstallerActivity != null
23645 && mInstantAppInstallerActivity.getComponentName().equals(component);
23650 public void pruneInstantApps() {
23651 mInstantAppRegistry.pruneInstantApps();
23655 public String getSetupWizardPackageName() {
23656 return mSetupWizardPackage;
23659 public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23660 if (policy != null) {
23661 mExternalSourcesPolicy = policy;
23666 public boolean isPackagePersistent(String packageName) {
23667 synchronized (mLock) {
23668 AndroidPackage pkg = mPackages.get(packageName);
23669 return pkg != null && pkg.isSystem() && pkg.isPersistent();
23674 public boolean isLegacySystemApp(AndroidPackage pkg) {
23675 synchronized (mLock) {
23676 final PackageSetting ps = getPackageSetting(pkg.getPackageName());
23677 return mPromoteSystemApps
23679 && mExistingSystemPackages.contains(ps.name);
23684 public List<PackageInfo> getOverlayPackages(int userId) {
23685 final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
23686 synchronized (mLock) {
23687 for (AndroidPackage p : mPackages.values()) {
23688 if (p.getOverlayTarget() != null) {
23689 PackageInfo pkg = generatePackageInfo(getPackageSetting(p.getPackageName()),
23692 overlayPackages.add(pkg);
23697 return overlayPackages;
23701 public List<String> getTargetPackageNames(int userId) {
23702 List<String> targetPackages = new ArrayList<>();
23703 synchronized (mLock) {
23704 for (AndroidPackage p : mPackages.values()) {
23705 if (p.getOverlayTarget() == null) {
23706 targetPackages.add(p.getPackageName());
23710 return targetPackages;
23714 public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
23715 @Nullable List<String> overlayPackageNames,
23716 @NonNull Collection<String> outUpdatedPackageNames) {
23717 synchronized (mLock) {
23718 final AndroidPackage targetPkg = mPackages.get(targetPackageName);
23719 if (targetPackageName == null || targetPkg == null) {
23720 Slog.e(TAG, "failed to find package " + targetPackageName);
23723 ArrayList<String> overlayPaths = null;
23724 if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
23725 final int N = overlayPackageNames.size();
23726 overlayPaths = new ArrayList<>(N);
23727 for (int i = 0; i < N; i++) {
23728 final String packageName = overlayPackageNames.get(i);
23729 final AndroidPackage pkg = mPackages.get(packageName);
23731 Slog.e(TAG, "failed to find package " + packageName);
23734 overlayPaths.add(pkg.getBaseCodePath());
23738 ArraySet<String> updatedPackageNames = null;
23739 if (targetPkg.getLibraryNames() != null) {
23740 // Set the overlay paths for dependencies of the shared library.
23741 updatedPackageNames = new ArraySet<>();
23742 for (String libName : targetPkg.getLibraryNames()) {
23743 final SharedLibraryInfo info = getSharedLibraryInfoLPr(libName,
23744 SharedLibraryInfo.VERSION_UNDEFINED);
23745 if (info == null) {
23748 final List<VersionedPackage> dependents = getPackagesUsingSharedLibraryLPr(
23750 if (dependents == null) {
23753 for (VersionedPackage dependent : dependents) {
23754 final PackageSetting ps = mSettings.mPackages.get(
23755 dependent.getPackageName());
23759 ps.setOverlayPathsForLibrary(libName, overlayPaths, userId);
23760 updatedPackageNames.add(dependent.getPackageName());
23765 final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
23766 ps.setOverlayPaths(overlayPaths, userId);
23768 outUpdatedPackageNames.add(targetPackageName);
23769 if (updatedPackageNames != null) {
23770 outUpdatedPackageNames.addAll(updatedPackageNames);
23778 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23779 int flags, int privateResolveFlags, int userId, boolean resolveForStart,
23780 int filterCallingUid) {
23781 return resolveIntentInternal(
23782 intent, resolvedType, flags, privateResolveFlags, userId, resolveForStart,
23787 public ResolveInfo resolveService(Intent intent, String resolvedType,
23788 int flags, int userId, int callingUid) {
23789 return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
23793 public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
23794 return PackageManagerService.this.resolveContentProviderInternal(
23795 name, flags, userId);
23799 public void addIsolatedUid(int isolatedUid, int ownerUid) {
23800 synchronized (mLock) {
23801 mIsolatedOwners.put(isolatedUid, ownerUid);
23806 public void removeIsolatedUid(int isolatedUid) {
23807 synchronized (mLock) {
23808 mIsolatedOwners.delete(isolatedUid);
23813 public int getUidTargetSdkVersion(int uid) {
23814 synchronized (mLock) {
23815 return getUidTargetSdkVersionLockedLPr(uid);
23820 public int getPackageTargetSdkVersion(String packageName) {
23821 synchronized (mLock) {
23822 return getPackageTargetSdkVersionLockedLPr(packageName);
23827 public boolean canAccessInstantApps(int callingUid, int userId) {
23828 return PackageManagerService.this.canViewInstantApps(callingUid, userId);
23832 public boolean canAccessComponent(int callingUid, ComponentName component, int userId) {
23833 synchronized (mLock) {
23834 final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
23835 return ps != null && !PackageManagerService.this.shouldFilterApplicationLocked(
23836 ps, callingUid, component, TYPE_UNKNOWN, userId);
23841 public boolean hasInstantApplicationMetadata(String packageName, int userId) {
23842 synchronized (mLock) {
23843 return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
23848 public void notifyPackageUse(String packageName, int reason) {
23849 synchronized (mLock) {
23850 PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
23855 public SparseArray<String> getAppsWithSharedUserIds() {
23856 synchronized (mLock) {
23857 return getAppsWithSharedUserIdsLocked();
23863 public String[] getSharedUserPackagesForPackage(String packageName, int userId) {
23864 synchronized (mLock) {
23865 return getSharedUserPackagesForPackageLocked(packageName, userId);
23870 public ArrayMap<String, ProcessInfo> getProcessesForUid(int uid) {
23871 synchronized (mLock) {
23872 return getProcessesForUidLocked(uid);
23877 public int[] getPermissionGids(String permissionName, int userId) {
23878 synchronized (mLock) {
23879 return getPermissionGidsLocked(permissionName, userId);
23884 public boolean isOnlyCoreApps() {
23885 return PackageManagerService.this.isOnlyCoreApps();
23889 public void freeStorage(String volumeUuid, long bytes, int storageFlags)
23890 throws IOException {
23891 PackageManagerService.this.freeStorage(volumeUuid, bytes, storageFlags);
23895 public void forEachPackage(Consumer<AndroidPackage> actionLocked) {
23896 PackageManagerService.this.forEachPackage(actionLocked);
23900 public void forEachPackageSetting(Consumer<PackageSetting> actionLocked) {
23901 synchronized (mLock) {
23902 for (int index = 0; index < mSettings.mPackages.size(); index++) {
23903 actionLocked.accept(mSettings.mPackages.valueAt(index));
23909 public void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> actionLocked,
23910 @UserIdInt int userId) {
23911 PackageManagerService.this.forEachInstalledPackage(actionLocked, userId);
23915 public ArraySet<String> getEnabledComponents(String packageName, int userId) {
23916 synchronized (mLock) {
23917 PackageSetting setting = mSettings.getPackageLPr(packageName);
23918 if (setting == null) {
23919 return new ArraySet<>();
23921 return setting.getEnabledComponents(userId);
23926 public ArraySet<String> getDisabledComponents(String packageName, int userId) {
23927 synchronized (mLock) {
23928 PackageSetting setting = mSettings.getPackageLPr(packageName);
23929 if (setting == null) {
23930 return new ArraySet<>();
23932 return setting.getDisabledComponents(userId);
23937 public @PackageManager.EnabledState int getApplicationEnabledState(
23938 String packageName, int userId) {
23939 synchronized (mLock) {
23940 PackageSetting setting = mSettings.getPackageLPr(packageName);
23941 if (setting == null) {
23942 return COMPONENT_ENABLED_STATE_DEFAULT;
23944 return setting.getEnabled(userId);
23949 public void setEnableRollbackCode(int token, int enableRollbackCode) {
23950 PackageManagerService.this.setEnableRollbackCode(token, enableRollbackCode);
23954 * Ask the package manager to compile layouts in the given package.
23957 public boolean compileLayouts(String packageName) {
23958 AndroidPackage pkg;
23959 synchronized (mLock) {
23960 pkg = mPackages.get(packageName);
23965 return mArtManagerService.compileLayouts(pkg);
23969 public void finishPackageInstall(int token, boolean didLaunch) {
23970 PackageManagerService.this.finishPackageInstall(token, didLaunch);
23975 public String removeLegacyDefaultBrowserPackageName(int userId) {
23976 synchronized (mLock) {
23977 return mSettings.removeDefaultBrowserPackageNameLPw(userId);
23982 public boolean isApexPackage(String packageName) {
23983 return PackageManagerService.this.mApexManager.isApexPackage(packageName);
23987 public List<String> getApksInApex(String apexPackageName) {
23988 return PackageManagerService.this.mApexManager.getApksInApex(apexPackageName);
23992 public void uninstallApex(String packageName, long versionCode, int userId,
23993 IntentSender intentSender, int flags) {
23994 final int callerUid = Binder.getCallingUid();
23995 if (callerUid != Process.ROOT_UID && callerUid != Process.SHELL_UID) {
23996 throw new SecurityException("Not allowed to uninstall apexes");
23998 PackageInstallerService.PackageDeleteObserverAdapter adapter =
23999 new PackageInstallerService.PackageDeleteObserverAdapter(
24000 PackageManagerService.this.mContext, intentSender, packageName,
24002 if ((flags & PackageManager.DELETE_ALL_USERS) == 0) {
24003 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
24004 "Can't uninstall an apex for a single user");
24007 final ApexManager am = PackageManagerService.this.mApexManager;
24008 PackageInfo activePackage = am.getPackageInfo(packageName,
24009 ApexManager.MATCH_ACTIVE_PACKAGE);
24010 if (activePackage == null) {
24011 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
24012 packageName + " is not an apex package");
24015 if (versionCode != PackageManager.VERSION_CODE_HIGHEST
24016 && activePackage.getLongVersionCode() != versionCode) {
24017 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
24018 "Active version " + activePackage.getLongVersionCode()
24019 + " is not equal to " + versionCode + "]");
24022 if (!am.uninstallApex(activePackage.applicationInfo.sourceDir)) {
24023 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
24024 "Failed to uninstall apex " + packageName);
24026 adapter.onPackageDeleted(packageName, PackageManager.DELETE_SUCCEEDED,
24032 public void setRuntimePermissionsFingerPrint(@NonNull String fingerPrint,
24033 @UserIdInt int userId) {
24034 synchronized (mLock) {
24035 mSettings.setRuntimePermissionsFingerPrintLPr(fingerPrint, userId);
24040 public void migrateLegacyObbData() {
24042 mInstaller.migrateLegacyObbData();
24043 } catch (Exception e) {
24049 public void writeSettings(boolean async) {
24050 synchronized (mLock) {
24052 scheduleWriteSettingsLocked();
24054 mSettings.writeLPr();
24060 public void writePermissionSettings(int[] userIds, boolean async) {
24061 synchronized (mLock) {
24062 for (int userId : userIds) {
24063 mSettings.writeRuntimePermissionsForUserLPr(userId, !async);
24069 public boolean isCallerInstallerOfRecord(
24070 @NonNull AndroidPackage pkg, int callingUid) {
24071 synchronized (mLock) {
24075 final PackageSetting packageSetting = getPackageSetting(pkg.getPackageName());
24076 if (packageSetting == null) {
24079 final PackageSetting installerPackageSetting =
24080 mSettings.mPackages.get(packageSetting.installSource.installerPackageName);
24081 return installerPackageSetting != null
24082 && UserHandle.isSameApp(installerPackageSetting.appId, callingUid);
24087 public boolean areDefaultRuntimePermissionsGranted(int userId) {
24088 synchronized (mLock) {
24089 return mSettings.areDefaultRuntimePermissionsGrantedLPr(userId);
24094 public void setReadExternalStorageEnforced(boolean enforced) {
24095 synchronized (mLock) {
24096 if (mSettings.mReadExternalStorageEnforced != null
24097 && mSettings.mReadExternalStorageEnforced == enforced) {
24100 mSettings.mReadExternalStorageEnforced = enforced ? Boolean.TRUE : Boolean.FALSE;
24101 mSettings.writeLPr();
24106 public void setIntegrityVerificationResult(int verificationId, int verificationResult) {
24107 final Message msg = mHandler.obtainMessage(INTEGRITY_VERIFICATION_COMPLETE);
24108 msg.arg1 = verificationId;
24109 msg.obj = verificationResult;
24110 mHandler.sendMessage(msg);
24114 public List<String> getMimeGroup(String packageName, String mimeGroup) {
24115 return PackageManagerService.this.getMimeGroup(packageName, mimeGroup);
24119 @GuardedBy("mLock")
24120 private SparseArray<String> getAppsWithSharedUserIdsLocked() {
24121 final SparseArray<String> sharedUserIds = new SparseArray<>();
24122 synchronized (mLock) {
24123 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
24124 sharedUserIds.put(UserHandle.getAppId(setting.userId), setting.name);
24127 return sharedUserIds;
24130 @GuardedBy("mLock")
24132 private String[] getSharedUserPackagesForPackageLocked(String packageName, int userId) {
24133 final PackageSetting packageSetting = mSettings.mPackages.get(packageName);
24134 if (packageSetting == null || !packageSetting.isSharedUser()) {
24135 return EmptyArray.STRING;
24138 ArraySet<PackageSetting> packages = packageSetting.sharedUser.packages;
24139 String[] res = new String[packages.size()];
24140 final Iterator<PackageSetting> it = packages.iterator();
24142 while (it.hasNext()) {
24143 PackageSetting ps = it.next();
24144 if (ps.getInstalled(userId)) {
24145 res[i++] = ps.name;
24148 res = ArrayUtils.trimToSize(res, i);
24149 return res != null ? res : EmptyArray.STRING;
24152 @GuardedBy("mLock")
24153 public ArrayMap<String, ProcessInfo> getProcessesForUidLocked(int uid) {
24154 final int appId = UserHandle.getAppId(uid);
24155 final SettingBase obj = mSettings.getSettingLPr(appId);
24156 if (obj instanceof SharedUserSetting) {
24157 final SharedUserSetting sus = (SharedUserSetting) obj;
24158 return PackageInfoUtils.generateProcessInfo(sus.processes, 0);
24159 } else if (obj instanceof PackageSetting) {
24160 final PackageSetting ps = (PackageSetting) obj;
24161 return PackageInfoUtils.generateProcessInfo(ps.pkg.getProcesses(), 0);
24166 @GuardedBy("mLock")
24167 public int[] getPermissionGidsLocked(String permissionName, int userId) {
24168 BasePermission perm
24169 = mPermissionManager.getPermissionSettings().getPermission(permissionName);
24170 if (perm != null) {
24171 return perm.computeGids(userId);
24177 public int getRuntimePermissionsVersion(@UserIdInt int userId) {
24178 Preconditions.checkArgumentNonnegative(userId);
24179 enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
24180 "getRuntimePermissionVersion");
24181 synchronized (mLock) {
24182 return mSettings.getDefaultRuntimePermissionsVersionLPr(userId);
24187 public void setRuntimePermissionsVersion(int version, @UserIdInt int userId) {
24188 Preconditions.checkArgumentNonnegative(version);
24189 Preconditions.checkArgumentNonnegative(userId);
24190 enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
24191 "setRuntimePermissionVersion");
24192 synchronized (mLock) {
24193 mSettings.setDefaultRuntimePermissionsVersionLPr(version, userId);
24197 private void enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
24198 @NonNull String message) {
24199 if (mContext.checkCallingOrSelfPermission(
24200 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY)
24201 != PackageManager.PERMISSION_GRANTED
24202 && mContext.checkCallingOrSelfPermission(
24203 Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS)
24204 != PackageManager.PERMISSION_GRANTED) {
24205 throw new SecurityException(message + " requires "
24206 + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " or "
24207 + Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS);
24212 public PackageSetting getPackageSetting(String packageName) {
24213 return getPackageSettingInternal(packageName, Binder.getCallingUid());
24216 private PackageSetting getPackageSettingInternal(String packageName, int callingUid) {
24217 synchronized (mLock) {
24218 packageName = resolveInternalPackageNameInternalLocked(
24219 packageName, PackageManager.VERSION_CODE_HIGHEST, callingUid);
24220 return mSettings.mPackages.get(packageName);
24224 void forEachPackage(Consumer<AndroidPackage> actionLocked) {
24225 synchronized (mLock) {
24226 int numPackages = mPackages.size();
24227 for (int i = 0; i < numPackages; i++) {
24228 actionLocked.accept(mPackages.valueAt(i));
24233 void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> actionLocked,
24234 @UserIdInt int userId) {
24235 synchronized (mLock) {
24236 int numPackages = mPackages.size();
24237 for (int i = 0; i < numPackages; i++) {
24238 AndroidPackage pkg = mPackages.valueAt(i);
24239 PackageSetting setting = mSettings.getPackageLPr(pkg.getPackageName());
24240 if (setting == null || !setting.getInstalled(userId)) {
24243 actionLocked.accept(pkg);
24248 boolean isHistoricalPackageUsageAvailable() {
24249 return mPackageUsage.isHistoricalPackageUsageAvailable();
24253 * Return a <b>copy</b> of the collection of packages known to the package manager.
24254 * @return A copy of the values of mPackages.
24256 Collection<AndroidPackage> getPackages() {
24257 synchronized (mLock) {
24258 return new ArrayList<>(mPackages.values());
24263 * Logs process start information (including base APK hash) to the security log.
24267 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
24268 String apkFile, int pid) {
24269 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24272 if (!SecurityLog.isLoggingEnabled()) {
24275 Bundle data = new Bundle();
24276 data.putLong("startTimestamp", System.currentTimeMillis());
24277 data.putString("processName", processName);
24278 data.putInt("uid", uid);
24279 data.putString("seinfo", seinfo);
24280 data.putString("apkFile", apkFile);
24281 data.putInt("pid", pid);
24282 Message msg = mProcessLoggingHandler.obtainMessage(
24283 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
24285 mProcessLoggingHandler.sendMessage(msg);
24288 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
24289 return mCompilerStats.getPackageStats(pkgName);
24292 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(AndroidPackage pkg) {
24293 return getOrCreateCompilerPackageStats(pkg.getPackageName());
24296 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
24297 return mCompilerStats.getOrCreatePackageStats(pkgName);
24300 public void deleteCompilerPackageStats(String pkgName) {
24301 mCompilerStats.deletePackageStats(pkgName);
24305 public int getInstallReason(String packageName, int userId) {
24306 final int callingUid = Binder.getCallingUid();
24307 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24308 true /* requireFullPermission */, false /* checkShell */,
24309 "get install reason");
24310 synchronized (mLock) {
24311 final PackageSetting ps = mSettings.mPackages.get(packageName);
24312 if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
24313 return PackageManager.INSTALL_REASON_UNKNOWN;
24316 return ps.getInstallReason(userId);
24319 return PackageManager.INSTALL_REASON_UNKNOWN;
24323 public boolean canRequestPackageInstalls(String packageName, int userId) {
24324 return canRequestPackageInstallsInternal(packageName, 0, userId,
24325 true /* throwIfPermNotDeclared*/);
24328 private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
24329 boolean throwIfPermNotDeclared) {
24330 int callingUid = Binder.getCallingUid();
24331 int uid = getPackageUid(packageName, 0, userId);
24332 if (callingUid != uid && callingUid != Process.ROOT_UID
24333 && callingUid != Process.SYSTEM_UID) {
24334 throw new SecurityException(
24335 "Caller uid " + callingUid + " does not own package " + packageName);
24337 ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
24338 if (info == null) {
24341 if (info.targetSdkVersion < Build.VERSION_CODES.O) {
24344 if (isInstantApp(packageName, userId)) {
24347 String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
24348 String[] packagesDeclaringPermission =
24349 mPermissionManager.getAppOpPermissionPackages(appOpPermission, callingUid);
24350 if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
24351 if (throwIfPermNotDeclared) {
24352 throw new SecurityException("Need to declare " + appOpPermission
24353 + " to call this api");
24355 Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
24359 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)
24360 || mUserManager.hasUserRestriction(
24361 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, userId)) {
24364 if (mExternalSourcesPolicy != null) {
24365 int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
24366 return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
24372 public ComponentName getInstantAppResolverSettingsComponent() {
24373 return mInstantAppResolverSettingsComponent;
24377 public ComponentName getInstantAppInstallerComponent() {
24378 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24381 return mInstantAppInstallerActivity == null
24382 ? null : mInstantAppInstallerActivity.getComponentName();
24386 public String getInstantAppAndroidId(String packageName, int userId) {
24387 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
24388 "getInstantAppAndroidId");
24389 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
24390 true /* requireFullPermission */, false /* checkShell */,
24391 "getInstantAppAndroidId");
24392 // Make sure the target is an Instant App.
24393 if (!isInstantApp(packageName, userId)) {
24396 synchronized (mLock) {
24397 return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
24401 boolean canHaveOatDir(String packageName) {
24402 synchronized (mLock) {
24403 AndroidPackage p = mPackages.get(packageName);
24404 PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
24405 if (p == null || pkgSetting == null) {
24408 return AndroidPackageUtils.canHaveOatDir(p,
24409 pkgSetting.getPkgState().isUpdatedSystemApp());
24413 private String getOatDir(AndroidPackage pkg, @NonNull PackageSetting pkgSetting) {
24414 if (!AndroidPackageUtils.canHaveOatDir(pkg,
24415 pkgSetting.getPkgState().isUpdatedSystemApp())) {
24418 File codePath = new File(pkg.getCodePath());
24419 if (codePath.isDirectory()) {
24420 return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
24425 void deleteOatArtifactsOfPackage(String packageName) {
24426 final String[] instructionSets;
24427 final List<String> codePaths;
24428 final String oatDir;
24429 final AndroidPackage pkg;
24430 final PackageSetting pkgSetting;
24431 synchronized (mLock) {
24432 pkg = mPackages.get(packageName);
24433 pkgSetting = mSettings.getPackageLPr(packageName);
24435 instructionSets = getAppDexInstructionSets(
24436 AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting),
24437 AndroidPackageUtils.getSecondaryCpuAbi(pkg, pkgSetting));
24438 codePaths = AndroidPackageUtils.getAllCodePaths(pkg);
24439 oatDir = getOatDir(pkg, pkgSetting);
24441 for (String codePath : codePaths) {
24442 for (String isa : instructionSets) {
24444 mInstaller.deleteOdex(codePath, isa, oatDir);
24445 } catch (InstallerException e) {
24446 Log.e(TAG, "Failed deleting oat files for " + codePath, e);
24452 Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
24453 Set<String> unusedPackages = new HashSet<>();
24454 long currentTimeInMillis = System.currentTimeMillis();
24455 synchronized (mLock) {
24456 for (AndroidPackage pkg : mPackages.values()) {
24457 PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
24461 PackageDexUsage.PackageUseInfo packageUseInfo =
24462 getDexManager().getPackageUseInfoOrDefault(pkg.getPackageName());
24463 if (PackageManagerServiceUtils
24464 .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
24465 downgradeTimeThresholdMillis, packageUseInfo,
24466 ps.getPkgState().getLatestPackageUseTimeInMills(),
24467 ps.getPkgState().getLatestForegroundPackageUseTimeInMills())) {
24468 unusedPackages.add(pkg.getPackageName());
24472 return unusedPackages;
24476 public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
24478 final int callingUid = Binder.getCallingUid();
24479 final int callingAppId = UserHandle.getAppId(callingUid);
24481 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24482 true /*requireFullPermission*/, true /*checkShell*/, "setHarmfulAppInfo");
24484 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
24485 checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
24486 throw new SecurityException("Caller must have the "
24487 + SET_HARMFUL_APP_WARNINGS + " permission.");
24490 synchronized (mLock) {
24491 mSettings.setHarmfulAppWarningLPw(packageName, warning, userId);
24492 scheduleWritePackageRestrictionsLocked(userId);
24498 public CharSequence getHarmfulAppWarning(@NonNull String packageName, int userId) {
24499 final int callingUid = Binder.getCallingUid();
24500 final int callingAppId = UserHandle.getAppId(callingUid);
24502 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24503 true /*requireFullPermission*/, true /*checkShell*/, "getHarmfulAppInfo");
24505 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
24506 checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
24507 throw new SecurityException("Caller must have the "
24508 + SET_HARMFUL_APP_WARNINGS + " permission.");
24511 synchronized (mLock) {
24512 return mSettings.getHarmfulAppWarningLPr(packageName, userId);
24517 public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) {
24518 final int callingUid = Binder.getCallingUid();
24519 final int callingAppId = UserHandle.getAppId(callingUid);
24521 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24522 false /*requireFullPermission*/, true /*checkShell*/, "isPackageStateProtected");
24524 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID
24525 && checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid) != PERMISSION_GRANTED) {
24526 throw new SecurityException("Caller must have the "
24527 + MANAGE_DEVICE_ADMINS + " permission.");
24530 return mProtectedPackages.isPackageStateProtected(userId, packageName);
24534 public void sendDeviceCustomizationReadyBroadcast() {
24535 mContext.enforceCallingPermission(Manifest.permission.SEND_DEVICE_CUSTOMIZATION_READY,
24536 "sendDeviceCustomizationReadyBroadcast");
24538 final long ident = Binder.clearCallingIdentity();
24540 final Intent intent = new Intent(Intent.ACTION_DEVICE_CUSTOMIZATION_READY);
24541 intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
24542 final IActivityManager am = ActivityManager.getService();
24543 final String[] requiredPermissions = {
24544 Manifest.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY,
24547 am.broadcastIntentWithFeature(null, null, intent, null, null, 0, null, null,
24548 requiredPermissions, android.app.AppOpsManager.OP_NONE, null, false, false,
24549 UserHandle.USER_ALL);
24550 } catch (RemoteException e) {
24551 throw e.rethrowFromSystemServer();
24554 Binder.restoreCallingIdentity(ident);
24558 private void applyMimeGroupChanges(String packageName, String mimeGroup) {
24559 if (mComponentResolver.updateMimeGroup(packageName, mimeGroup)) {
24560 clearPackagePreferredActivities(packageName, UserHandle.USER_ALL);
24563 mPmInternal.writeSettings(false);
24567 public void setMimeGroup(String packageName, String mimeGroup, List<String> mimeTypes) {
24568 boolean changed = mSettings.mPackages.get(packageName)
24569 .setMimeGroup(mimeGroup, mimeTypes);
24572 applyMimeGroupChanges(packageName, mimeGroup);
24577 public void clearMimeGroup(String packageName, String mimeGroup) {
24578 boolean changed = mSettings.mPackages.get(packageName).clearMimeGroup(mimeGroup);
24581 applyMimeGroupChanges(packageName, mimeGroup);
24586 public List<String> getMimeGroup(String packageName, String mimeGroup) {
24587 return mSettings.mPackages.get(packageName).getMimeGroup(mimeGroup);
24590 static class ActiveInstallSession {
24591 private final String mPackageName;
24592 private final File mStagedDir;
24593 private final IPackageInstallObserver2 mObserver;
24594 private final int mSessionId;
24595 private final PackageInstaller.SessionParams mSessionParams;
24596 private final int mInstallerUid;
24597 @NonNull private final InstallSource mInstallSource;
24598 private final UserHandle mUser;
24599 private final SigningDetails mSigningDetails;
24601 ActiveInstallSession(String packageName, File stagedDir, IPackageInstallObserver2 observer,
24602 int sessionId, PackageInstaller.SessionParams sessionParams, int installerUid,
24603 InstallSource installSource, UserHandle user, SigningDetails signingDetails) {
24604 mPackageName = packageName;
24605 mStagedDir = stagedDir;
24606 mObserver = observer;
24607 mSessionId = sessionId;
24608 mSessionParams = sessionParams;
24609 mInstallerUid = installerUid;
24610 mInstallSource = Preconditions.checkNotNull(installSource);
24612 mSigningDetails = signingDetails;
24615 public String getPackageName() {
24616 return mPackageName;
24619 public File getStagedDir() {
24623 public IPackageInstallObserver2 getObserver() {
24627 public int getSessionId() {
24631 public PackageInstaller.SessionParams getSessionParams() {
24632 return mSessionParams;
24635 public int getInstallerUid() {
24636 return mInstallerUid;
24640 public InstallSource getInstallSource() {
24641 return mInstallSource;
24644 public UserHandle getUser() {
24648 public SigningDetails getSigningDetails() {
24649 return mSigningDetails;
24654 interface PackageSender {
24656 * @param userIds User IDs where the action occurred on a full application
24657 * @param instantUserIds User IDs where the action occurred on an instant application
24659 void sendPackageBroadcast(final String action, final String pkg,
24660 final Bundle extras, final int flags, final String targetPkg,
24661 final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds);
24662 void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
24663 boolean includeStopped, int appId, int[] userIds, int[] instantUserIds);
24664 void notifyPackageAdded(String packageName, int uid);
24665 void notifyPackageChanged(String packageName, int uid);
24666 void notifyPackageRemoved(String packageName, int uid);