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.pm.PackageManager.CERT_INPUT_RAW_X509;
31 import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
32 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
33 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
34 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
35 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
36 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
37 import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
38 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
39 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
40 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
41 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
42 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
43 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
44 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
45 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
46 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
47 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
48 import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
49 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
50 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
51 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
52 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
53 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
54 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
55 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
56 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
57 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
58 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
59 import static android.content.pm.PackageManager.INSTALL_INTERNAL;
60 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
61 import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
62 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
63 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
64 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
65 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
66 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
67 import static android.content.pm.PackageManager.MATCH_ALL;
68 import static android.content.pm.PackageManager.MATCH_ANY_USER;
69 import static android.content.pm.PackageManager.MATCH_APEX;
70 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
71 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
72 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
73 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
74 import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
75 import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
76 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
77 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
78 import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
79 import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
80 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
81 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
82 import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
83 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
84 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
85 import static android.content.pm.PackageManager.PERMISSION_DENIED;
86 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
87 import static android.content.pm.PackageManager.RESTRICTION_NONE;
88 import static android.content.pm.PackageParser.isApkFile;
89 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
90 import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
91 import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
92 import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
94 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
95 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
96 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
97 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
98 import static com.android.server.pm.ComponentResolver.RESOLVE_PRIORITY_SORTER;
99 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
100 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
101 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
102 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
103 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
104 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
105 import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
106 import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
107 import static com.android.server.pm.PackageManagerServiceUtils.decompressFile;
108 import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
109 import static com.android.server.pm.PackageManagerServiceUtils.dumpCriticalInfo;
110 import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFiles;
111 import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
112 import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
113 import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
115 import android.Manifest;
116 import android.annotation.IntDef;
117 import android.annotation.NonNull;
118 import android.annotation.Nullable;
119 import android.annotation.UserIdInt;
120 import android.app.ActivityManager;
121 import android.app.ActivityManagerInternal;
122 import android.app.AppOpsManager;
123 import android.app.BroadcastOptions;
124 import android.app.IActivityManager;
125 import android.app.ResourcesManager;
126 import android.app.admin.IDevicePolicyManager;
127 import android.app.admin.SecurityLog;
128 import android.app.backup.IBackupManager;
129 import android.content.BroadcastReceiver;
130 import android.content.ComponentName;
131 import android.content.ContentResolver;
132 import android.content.Context;
133 import android.content.IIntentReceiver;
134 import android.content.Intent;
135 import android.content.IntentFilter;
136 import android.content.IntentSender;
137 import android.content.IntentSender.SendIntentException;
138 import android.content.pm.ActivityInfo;
139 import android.content.pm.ApplicationInfo;
140 import android.content.pm.AppsQueryHelper;
141 import android.content.pm.AuxiliaryResolveInfo;
142 import android.content.pm.ChangedPackages;
143 import android.content.pm.ComponentInfo;
144 import android.content.pm.FallbackCategoryProvider;
145 import android.content.pm.FeatureInfo;
146 import android.content.pm.IDexModuleRegisterCallback;
147 import android.content.pm.IOnPermissionsChangeListener;
148 import android.content.pm.IPackageDataObserver;
149 import android.content.pm.IPackageDeleteObserver;
150 import android.content.pm.IPackageDeleteObserver2;
151 import android.content.pm.IPackageInstallObserver2;
152 import android.content.pm.IPackageInstaller;
153 import android.content.pm.IPackageManager;
154 import android.content.pm.IPackageManagerNative;
155 import android.content.pm.IPackageMoveObserver;
156 import android.content.pm.IPackageStatsObserver;
157 import android.content.pm.InstantAppInfo;
158 import android.content.pm.InstantAppRequest;
159 import android.content.pm.InstrumentationInfo;
160 import android.content.pm.IntentFilterVerificationInfo;
161 import android.content.pm.KeySet;
162 import android.content.pm.ModuleInfo;
163 import android.content.pm.PackageBackwardCompatibility;
164 import android.content.pm.PackageInfo;
165 import android.content.pm.PackageInfoLite;
166 import android.content.pm.PackageInstaller;
167 import android.content.pm.PackageList;
168 import android.content.pm.PackageManager;
169 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
170 import android.content.pm.PackageManager.ModuleInfoFlags;
171 import android.content.pm.PackageManager.PermissionWhitelistFlags;
172 import android.content.pm.PackageManagerInternal;
173 import android.content.pm.PackageManagerInternal.CheckPermissionDelegate;
174 import android.content.pm.PackageManagerInternal.PackageListObserver;
175 import android.content.pm.PackageParser;
176 import android.content.pm.PackageParser.ActivityIntentInfo;
177 import android.content.pm.PackageParser.PackageLite;
178 import android.content.pm.PackageParser.PackageParserException;
179 import android.content.pm.PackageParser.ParseFlags;
180 import android.content.pm.PackageParser.SigningDetails;
181 import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
182 import android.content.pm.PackageStats;
183 import android.content.pm.PackageUserState;
184 import android.content.pm.ParceledListSlice;
185 import android.content.pm.PermissionGroupInfo;
186 import android.content.pm.PermissionInfo;
187 import android.content.pm.ProviderInfo;
188 import android.content.pm.ResolveInfo;
189 import android.content.pm.SELinuxUtil;
190 import android.content.pm.ServiceInfo;
191 import android.content.pm.SharedLibraryInfo;
192 import android.content.pm.Signature;
193 import android.content.pm.SuspendDialogInfo;
194 import android.content.pm.UserInfo;
195 import android.content.pm.VerifierDeviceIdentity;
196 import android.content.pm.VerifierInfo;
197 import android.content.pm.VersionedPackage;
198 import android.content.pm.dex.ArtManager;
199 import android.content.pm.dex.DexMetadataHelper;
200 import android.content.pm.dex.IArtManager;
201 import android.content.res.Resources;
202 import android.content.rollback.IRollbackManager;
203 import android.database.ContentObserver;
204 import android.graphics.Bitmap;
205 import android.hardware.display.DisplayManager;
206 import android.net.Uri;
207 import android.os.AsyncTask;
208 import android.os.Binder;
209 import android.os.Build;
210 import android.os.Bundle;
211 import android.os.Debug;
212 import android.os.Environment;
213 import android.os.FileUtils;
214 import android.os.Handler;
215 import android.os.IBinder;
216 import android.os.Looper;
217 import android.os.Message;
218 import android.os.Parcel;
219 import android.os.PatternMatcher;
220 import android.os.PersistableBundle;
221 import android.os.Process;
222 import android.os.RemoteCallbackList;
223 import android.os.RemoteException;
224 import android.os.ResultReceiver;
225 import android.os.SELinux;
226 import android.os.ServiceManager;
227 import android.os.ShellCallback;
228 import android.os.SystemClock;
229 import android.os.SystemProperties;
230 import android.os.Trace;
231 import android.os.UserHandle;
232 import android.os.UserManager;
233 import android.os.UserManagerInternal;
234 import android.os.storage.DiskInfo;
235 import android.os.storage.IStorageManager;
236 import android.os.storage.StorageEventListener;
237 import android.os.storage.StorageManager;
238 import android.os.storage.StorageManagerInternal;
239 import android.os.storage.VolumeInfo;
240 import android.os.storage.VolumeRecord;
241 import android.provider.DeviceConfig;
242 import android.provider.MediaStore;
243 import android.provider.Settings.Global;
244 import android.provider.Settings.Secure;
245 import android.security.KeyStore;
246 import android.security.SystemKeyStore;
247 import android.service.pm.PackageServiceDumpProto;
248 import android.stats.storage.StorageEnums;
249 import android.system.ErrnoException;
250 import android.system.Os;
251 import android.text.TextUtils;
252 import android.text.format.DateUtils;
253 import android.util.ArrayMap;
254 import android.util.ArraySet;
255 import android.util.Base64;
256 import android.util.ByteStringUtils;
257 import android.util.DisplayMetrics;
258 import android.util.EventLog;
259 import android.util.ExceptionUtils;
260 import android.util.IntArray;
261 import android.util.Log;
262 import android.util.LogPrinter;
263 import android.util.LongSparseArray;
264 import android.util.LongSparseLongArray;
265 import android.util.MathUtils;
266 import android.util.PackageUtils;
267 import android.util.Pair;
268 import android.util.PrintStreamPrinter;
269 import android.util.Slog;
270 import android.util.SparseArray;
271 import android.util.SparseBooleanArray;
272 import android.util.SparseIntArray;
273 import android.util.StatsLog;
274 import android.util.TimingsTraceLog;
275 import android.util.Xml;
276 import android.util.jar.StrictJarFile;
277 import android.util.proto.ProtoOutputStream;
278 import android.view.Display;
280 import com.android.internal.R;
281 import com.android.internal.annotations.GuardedBy;
282 import com.android.internal.app.ResolverActivity;
283 import com.android.internal.content.NativeLibraryHelper;
284 import com.android.internal.content.PackageHelper;
285 import com.android.internal.logging.MetricsLogger;
286 import com.android.internal.os.SomeArgs;
287 import com.android.internal.os.Zygote;
288 import com.android.internal.telephony.CarrierAppUtils;
289 import com.android.internal.util.ArrayUtils;
290 import com.android.internal.util.ConcurrentUtils;
291 import com.android.internal.util.DumpUtils;
292 import com.android.internal.util.FastXmlSerializer;
293 import com.android.internal.util.IndentingPrintWriter;
294 import com.android.internal.util.IntPair;
295 import com.android.internal.util.Preconditions;
296 import com.android.server.AttributeCache;
297 import com.android.server.DeviceIdleController;
298 import com.android.server.EventLogTags;
299 import com.android.server.FgThread;
300 import com.android.server.LocalServices;
301 import com.android.server.LockGuard;
302 import com.android.server.PackageWatchdog;
303 import com.android.server.ServiceThread;
304 import com.android.server.SystemConfig;
305 import com.android.server.SystemServerInitThreadPool;
306 import com.android.server.Watchdog;
307 import com.android.server.net.NetworkPolicyManagerInternal;
308 import com.android.server.pm.Installer.InstallerException;
309 import com.android.server.pm.Settings.DatabaseVersion;
310 import com.android.server.pm.Settings.VersionInfo;
311 import com.android.server.pm.dex.ArtManagerService;
312 import com.android.server.pm.dex.DexManager;
313 import com.android.server.pm.dex.DexoptOptions;
314 import com.android.server.pm.dex.PackageDexUsage;
315 import com.android.server.pm.dex.ViewCompiler;
316 import com.android.server.pm.permission.BasePermission;
317 import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
318 import com.android.server.pm.permission.PermissionManagerService;
319 import com.android.server.pm.permission.PermissionManagerServiceInternal;
320 import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
321 import com.android.server.pm.permission.PermissionsState;
322 import com.android.server.policy.PermissionPolicyInternal;
323 import com.android.server.security.VerityUtils;
324 import com.android.server.storage.DeviceStorageMonitorInternal;
325 import com.android.server.wm.ActivityTaskManagerInternal;
327 import dalvik.system.CloseGuard;
328 import dalvik.system.VMRuntime;
330 import libcore.io.IoUtils;
331 import libcore.util.EmptyArray;
333 import org.xmlpull.v1.XmlPullParser;
334 import org.xmlpull.v1.XmlPullParserException;
335 import org.xmlpull.v1.XmlSerializer;
337 import java.io.BufferedOutputStream;
338 import java.io.ByteArrayInputStream;
339 import java.io.ByteArrayOutputStream;
341 import java.io.FileDescriptor;
342 import java.io.FileInputStream;
343 import java.io.FileOutputStream;
344 import java.io.FilenameFilter;
345 import java.io.IOException;
346 import java.io.PrintWriter;
347 import java.lang.annotation.Retention;
348 import java.lang.annotation.RetentionPolicy;
349 import java.nio.charset.StandardCharsets;
350 import java.security.DigestException;
351 import java.security.DigestInputStream;
352 import java.security.MessageDigest;
353 import java.security.NoSuchAlgorithmException;
354 import java.security.PublicKey;
355 import java.security.SecureRandom;
356 import java.security.cert.CertificateException;
357 import java.util.ArrayList;
358 import java.util.Arrays;
359 import java.util.Collection;
360 import java.util.Collections;
361 import java.util.Comparator;
362 import java.util.HashMap;
363 import java.util.HashSet;
364 import java.util.Iterator;
365 import java.util.LinkedHashSet;
366 import java.util.List;
367 import java.util.Map;
368 import java.util.Objects;
369 import java.util.Set;
370 import java.util.concurrent.CountDownLatch;
371 import java.util.concurrent.Future;
372 import java.util.concurrent.TimeUnit;
373 import java.util.concurrent.atomic.AtomicBoolean;
374 import java.util.concurrent.atomic.AtomicInteger;
375 import java.util.function.BiConsumer;
376 import java.util.function.Consumer;
377 import java.util.function.Predicate;
380 * Keep track of all those APKs everywhere.
382 * Internally there are two important locks:
384 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
385 * and other related state. It is a fine-grained lock that should only be held
386 * momentarily, as it's one of the most contended locks in the system.
387 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
388 * operations typically involve heavy lifting of application data on disk. Since
389 * {@code installd} is single-threaded, and it's operations can often be slow,
390 * this lock should never be acquired while already holding {@link #mPackages}.
391 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
392 * holding {@link #mInstallLock}.
394 * Many internal methods rely on the caller to hold the appropriate locks, and
395 * this contract is expressed through method name suffixes:
397 * <li>fooLI(): the caller must hold {@link #mInstallLock}
398 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
399 * being modified must be frozen
400 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
401 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
404 * Because this class is very central to the platform's security; please run all
405 * CTS and unit tests whenever making modifications:
408 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
409 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
412 public class PackageManagerService extends IPackageManager.Stub
413 implements PackageSender {
414 static final String TAG = "PackageManager";
415 public static final boolean DEBUG_SETTINGS = false;
416 static final boolean DEBUG_PREFERRED = false;
417 static final boolean DEBUG_UPGRADE = false;
418 static final boolean DEBUG_DOMAIN_VERIFICATION = false;
419 private static final boolean DEBUG_BACKUP = false;
420 public static final boolean DEBUG_INSTALL = false;
421 public static final boolean DEBUG_REMOVE = false;
422 private static final boolean DEBUG_BROADCASTS = false;
423 private static final boolean DEBUG_PACKAGE_INFO = false;
424 private static final boolean DEBUG_INTENT_MATCHING = false;
425 public static final boolean DEBUG_PACKAGE_SCANNING = false;
426 private static final boolean DEBUG_VERIFY = false;
427 public static final boolean DEBUG_PERMISSIONS = false;
428 private static final boolean DEBUG_SHARED_LIBRARIES = false;
429 public static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
431 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
432 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
433 // user, but by default initialize to this.
434 public static final boolean DEBUG_DEXOPT = false;
436 private static final boolean DEBUG_ABI_SELECTION = false;
437 private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE;
438 private static final boolean DEBUG_APP_DATA = false;
440 /** REMOVE. According to Svet, this was only used to reset permissions during development. */
441 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
443 private static final boolean HIDE_EPHEMERAL_APIS = false;
445 private static final boolean ENABLE_FREE_CACHE_V2 =
446 SystemProperties.getBoolean("fw.free_cache_v2", true);
448 private static final String PRECOMPILE_LAYOUTS = "pm.precompile_layouts";
450 private static final int RADIO_UID = Process.PHONE_UID;
451 private static final int LOG_UID = Process.LOG_UID;
452 private static final int NFC_UID = Process.NFC_UID;
453 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
454 private static final int SHELL_UID = Process.SHELL_UID;
455 private static final int SE_UID = Process.SE_UID;
456 private static final int NETWORKSTACK_UID = Process.NETWORK_STACK_UID;
458 static final int SCAN_NO_DEX = 1 << 0;
459 static final int SCAN_UPDATE_SIGNATURE = 1 << 1;
460 static final int SCAN_NEW_INSTALL = 1 << 2;
461 static final int SCAN_UPDATE_TIME = 1 << 3;
462 static final int SCAN_BOOTING = 1 << 4;
463 static final int SCAN_REQUIRE_KNOWN = 1 << 7;
464 static final int SCAN_MOVE = 1 << 8;
465 static final int SCAN_INITIAL = 1 << 9;
466 static final int SCAN_CHECK_ONLY = 1 << 10;
467 static final int SCAN_DONT_KILL_APP = 1 << 11;
468 static final int SCAN_IGNORE_FROZEN = 1 << 12;
469 static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1 << 13;
470 static final int SCAN_AS_INSTANT_APP = 1 << 14;
471 static final int SCAN_AS_FULL_APP = 1 << 15;
472 static final int SCAN_AS_VIRTUAL_PRELOAD = 1 << 16;
473 static final int SCAN_AS_SYSTEM = 1 << 17;
474 static final int SCAN_AS_PRIVILEGED = 1 << 18;
475 static final int SCAN_AS_OEM = 1 << 19;
476 static final int SCAN_AS_VENDOR = 1 << 20;
477 static final int SCAN_AS_PRODUCT = 1 << 21;
478 static final int SCAN_AS_PRODUCT_SERVICES = 1 << 22;
479 static final int SCAN_AS_ODM = 1 << 23;
481 @IntDef(flag = true, prefix = { "SCAN_" }, value = {
483 SCAN_UPDATE_SIGNATURE,
493 SCAN_FIRST_BOOT_OR_UPGRADE,
496 SCAN_AS_VIRTUAL_PRELOAD,
498 @Retention(RetentionPolicy.SOURCE)
499 public @interface ScanFlags {}
501 private static final String STATIC_SHARED_LIB_DELIMITER = "_";
502 /** Extension of the compressed packages */
503 public final static String COMPRESSED_EXTENSION = ".gz";
504 /** Suffix of stub packages on the system partition */
505 public final static String STUB_SUFFIX = "-Stub";
507 private static final int[] EMPTY_INT_ARRAY = new int[0];
509 private static final int TYPE_UNKNOWN = 0;
510 private static final int TYPE_ACTIVITY = 1;
511 private static final int TYPE_RECEIVER = 2;
512 private static final int TYPE_SERVICE = 3;
513 private static final int TYPE_PROVIDER = 4;
514 @IntDef(prefix = { "TYPE_" }, value = {
521 @Retention(RetentionPolicy.SOURCE)
522 public @interface ComponentType {}
525 * Timeout (in milliseconds) after which the watchdog should declare that
526 * our handler thread is wedged. The usual default for such things is one
527 * minute but we sometimes do very lengthy I/O operations on this thread,
528 * such as installing multi-gigabyte applications, so ours needs to be longer.
530 static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes
533 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
534 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
535 * settings entry if available, otherwise we use the hardcoded default. If it's been
536 * more than this long since the last fstrim, we force one during the boot sequence.
538 * This backstops other fstrim scheduling: if the device is alive at midnight+idle,
539 * one gets run at the next available charging+idle time. This final mandatory
540 * no-fstrim check kicks in only of the other scheduling criteria is never met.
542 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
545 * Whether verification is enabled by default.
547 private static final boolean DEFAULT_VERIFY_ENABLE = true;
550 * The default maximum time to wait for the verification agent to return in
553 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
556 * Timeout duration in milliseconds for enabling package rollback. If we fail to enable
557 * rollback within that period, the install will proceed without rollback enabled.
559 * <p>If flag value is negative, the default value will be assigned.
561 * Flag type: {@code long}
562 * Namespace: NAMESPACE_ROLLBACK
564 private static final String PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS = "enable_rollback_timeout";
567 * The default duration to wait for rollback to be enabled in
570 private static final long DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS = 10 * 1000;
573 * The default response for package verification timeout.
575 * This can be either PackageManager.VERIFICATION_ALLOW or
576 * PackageManager.VERIFICATION_REJECT.
578 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
580 public static final String PLATFORM_PACKAGE_NAME = "android";
582 private static final String KILL_APP_REASON_GIDS_CHANGED =
583 "permission grant or revoke changed gids";
585 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
586 "permissions revoked";
588 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
590 private static final String PACKAGE_SCHEME = "package";
592 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
594 private static final String PRODUCT_OVERLAY_DIR = "/product/overlay";
596 private static final String PRODUCT_SERVICES_OVERLAY_DIR = "/product_services/overlay";
598 private static final String ODM_OVERLAY_DIR = "/odm/overlay";
600 private static final String OEM_OVERLAY_DIR = "/oem/overlay";
602 /** Canonical intent used to identify what counts as a "web browser" app */
603 private static final Intent sBrowserIntent;
605 sBrowserIntent = new Intent();
606 sBrowserIntent.setAction(Intent.ACTION_VIEW);
607 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
608 sBrowserIntent.setData(Uri.parse("http:"));
609 sBrowserIntent.addFlags(Intent.FLAG_IGNORE_EPHEMERAL);
612 // Compilation reasons.
613 public static final int REASON_UNKNOWN = -1;
614 public static final int REASON_FIRST_BOOT = 0;
615 public static final int REASON_BOOT = 1;
616 public static final int REASON_INSTALL = 2;
617 public static final int REASON_BACKGROUND_DEXOPT = 3;
618 public static final int REASON_AB_OTA = 4;
619 public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
620 public static final int REASON_SHARED = 6;
622 public static final int REASON_LAST = REASON_SHARED;
625 * Whether the package parser cache is enabled.
627 private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
630 * Permissions required in order to receive instant application lifecycle broadcasts.
632 private static final String[] INSTANT_APP_BROADCAST_PERMISSION =
633 new String[] { android.Manifest.permission.ACCESS_INSTANT_APPS };
635 final ServiceThread mHandlerThread;
637 final PackageHandler mHandler;
639 private final ProcessLoggingHandler mProcessLoggingHandler;
641 final int mSdkVersion = Build.VERSION.SDK_INT;
643 final Context mContext;
644 final boolean mFactoryTest;
645 final boolean mOnlyCore;
646 final DisplayMetrics mMetrics;
647 final int mDefParseFlags;
648 final String[] mSeparateProcesses;
649 final boolean mIsUpgrade;
650 final boolean mIsPreNUpgrade;
651 final boolean mIsPreNMR1Upgrade;
652 final boolean mIsPreQUpgrade;
654 @GuardedBy("mPackages")
655 private boolean mDexOptDialogShown;
657 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
658 // LOCK HELD. Can be called with mInstallLock held.
659 @GuardedBy("mInstallLock")
660 final Installer mInstaller;
662 /** Directory where installed applications are stored */
663 private static final File sAppInstallDir =
664 new File(Environment.getDataDirectory(), "app");
665 /** Directory where installed application's 32-bit native libraries are copied. */
666 private static final File sAppLib32InstallDir =
667 new File(Environment.getDataDirectory(), "app-lib");
669 // ----------------------------------------------------------------
671 // Lock for state used when installing and doing other long running
672 // operations. Methods that must be called with this lock held have
674 final Object mInstallLock = new Object();
676 // ----------------------------------------------------------------
678 // Keys are String (package name), values are Package. This also serves
679 // as the lock for the global state. Methods that must be called with
680 // this lock held have the prefix "LP".
681 @GuardedBy("mPackages")
682 final ArrayMap<String, PackageParser.Package> mPackages = new ArrayMap<>();
684 // Keys are isolated uids and values are the uid of the application
685 // that created the isolated proccess.
686 @GuardedBy("mPackages")
687 final SparseIntArray mIsolatedOwners = new SparseIntArray();
690 * Tracks new system packages [received in an OTA] that we expect to
691 * find updated user-installed versions. Keys are package name, values
692 * are package location.
694 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
697 * Tracks existing system packages prior to receiving an OTA. Keys are package name.
699 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
701 * Whether or not system app permissions should be promoted from install to runtime.
703 boolean mPromoteSystemApps;
705 @GuardedBy("mPackages")
706 final Settings mSettings;
709 * Set of package names that are currently "frozen", which means active
710 * surgery is being done on the code/data for that package. The platform
711 * will refuse to launch frozen packages to avoid race conditions.
713 * @see PackageFreezer
715 @GuardedBy("mPackages")
716 final ArraySet<String> mFrozenPackages = new ArraySet<>();
718 final ProtectedPackages mProtectedPackages;
720 @GuardedBy("mLoadedVolumes")
721 final ArraySet<String> mLoadedVolumes = new ArraySet<>();
725 PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
727 @GuardedBy("mAvailableFeatures")
728 final ArrayMap<String, FeatureInfo> mAvailableFeatures;
730 private final InstantAppRegistry mInstantAppRegistry;
732 @GuardedBy("mPackages")
733 int mChangedPackagesSequenceNumber;
735 * List of changed [installed, removed or updated] packages.
736 * mapping from user id -> sequence number -> package name
738 @GuardedBy("mPackages")
739 final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
741 * The sequence number of the last change to a package.
742 * mapping from user id -> package name -> sequence number
744 @GuardedBy("mPackages")
745 final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
747 @GuardedBy("mPackages")
748 final private ArraySet<PackageListObserver> mPackageListObservers = new ArraySet<>();
750 @GuardedBy("mPackages")
751 private final SparseIntArray mDefaultPermissionsGrantedUsers = new SparseIntArray();
753 private final ModuleInfoProvider mModuleInfoProvider;
755 private final ApexManager mApexManager;
757 class PackageParserCallback implements PackageParser.Callback {
758 @Override public final boolean hasFeature(String feature) {
759 return PackageManagerService.this.hasSystemFeature(feature, 0);
762 final List<PackageParser.Package> getStaticOverlayPackages(
763 Collection<PackageParser.Package> allPackages, String targetPackageName) {
764 if ("android".equals(targetPackageName)) {
765 // Static RROs targeting to "android", ie framework-res.apk, are already applied by
766 // native AssetManager.
770 List<PackageParser.Package> overlayPackages = null;
771 for (PackageParser.Package p : allPackages) {
772 if (targetPackageName.equals(p.mOverlayTarget) && p.mOverlayIsStatic) {
773 if (overlayPackages == null) {
774 overlayPackages = new ArrayList<>();
776 overlayPackages.add(p);
779 if (overlayPackages != null) {
780 Comparator<PackageParser.Package> cmp =
781 Comparator.comparingInt(p -> p.mOverlayPriority);
782 overlayPackages.sort(cmp);
784 return overlayPackages;
787 final String[] getStaticOverlayPaths(List<PackageParser.Package> overlayPackages,
789 if (overlayPackages == null || overlayPackages.isEmpty()) {
792 List<String> overlayPathList = null;
793 for (PackageParser.Package overlayPackage : overlayPackages) {
794 if (targetPath == null) {
795 if (overlayPathList == null) {
796 overlayPathList = new ArrayList<>();
798 overlayPathList.add(overlayPackage.baseCodePath);
803 // Creates idmaps for system to parse correctly the Android manifest of the
806 // OverlayManagerService will update each of them with a correct gid from its
807 // target package app id.
808 mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
809 UserHandle.getSharedAppGid(
810 UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
811 if (overlayPathList == null) {
812 overlayPathList = new ArrayList<>();
814 overlayPathList.add(overlayPackage.baseCodePath);
815 } catch (InstallerException e) {
816 Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
817 overlayPackage.baseCodePath);
820 return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
823 String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
824 List<PackageParser.Package> overlayPackages;
825 synchronized (mInstallLock) {
826 synchronized (mPackages) {
827 overlayPackages = getStaticOverlayPackages(
828 mPackages.values(), targetPackageName);
830 // It is safe to keep overlayPackages without holding mPackages because static overlay
831 // packages can't be uninstalled or disabled.
832 return getStaticOverlayPaths(overlayPackages, targetPath);
836 @Override public final String[] getOverlayApks(String targetPackageName) {
837 return getStaticOverlayPaths(targetPackageName, null);
840 @Override public final String[] getOverlayPaths(String targetPackageName,
842 return getStaticOverlayPaths(targetPackageName, targetPath);
846 class ParallelPackageParserCallback extends PackageParserCallback {
847 List<PackageParser.Package> mOverlayPackages = null;
849 void findStaticOverlayPackages() {
850 synchronized (mPackages) {
851 for (PackageParser.Package p : mPackages.values()) {
852 if (p.mOverlayIsStatic) {
853 if (mOverlayPackages == null) {
854 mOverlayPackages = new ArrayList<>();
856 mOverlayPackages.add(p);
863 synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
864 // We can trust mOverlayPackages without holding mPackages because package uninstall
865 // can't happen while running parallel parsing.
866 // And we can call mInstaller inside getStaticOverlayPaths without holding mInstallLock
867 // because mInstallLock is held before running parallel parsing.
868 // Moreover holding mPackages or mInstallLock on each parsing thread causes dead-lock.
869 return mOverlayPackages == null ? null :
870 getStaticOverlayPaths(
871 getStaticOverlayPackages(mOverlayPackages, targetPackageName),
876 final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
877 final ParallelPackageParserCallback mParallelPackageParserCallback =
878 new ParallelPackageParserCallback();
880 // Currently known shared libraries.
881 final ArrayMap<String, LongSparseArray<SharedLibraryInfo>> mSharedLibraries = new ArrayMap<>();
882 final ArrayMap<String, LongSparseArray<SharedLibraryInfo>> mStaticLibsByDeclaringPackage =
885 // Mapping from instrumentation class names to info about them.
886 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
889 // Packages whose data we have transfered into another package, thus
890 // should no longer exist.
891 final ArraySet<String> mTransferedPackages = new ArraySet<>();
893 // Broadcast actions that are only available to the system.
894 @GuardedBy("mProtectedBroadcasts")
895 final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
897 /** List of packages waiting for verification. */
898 final SparseArray<PackageVerificationState> mPendingVerification = new SparseArray<>();
900 /** List of packages waiting for rollback to be enabled. */
901 final SparseArray<InstallParams> mPendingEnableRollback = new SparseArray<>();
903 final PackageInstallerService mInstallerService;
905 final ArtManagerService mArtManagerService;
907 private final PackageDexOptimizer mPackageDexOptimizer;
908 // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
909 // is used by other apps).
910 private final DexManager mDexManager;
912 private final ViewCompiler mViewCompiler;
914 private AtomicInteger mNextMoveId = new AtomicInteger();
915 private final MoveCallbacks mMoveCallbacks;
917 private final OnPermissionChangeListeners mOnPermissionChangeListeners;
919 // Cache of users who need badging.
920 private final SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
922 /** Token for keys in mPendingVerification. */
923 private int mPendingVerificationToken = 0;
925 /** Token for keys in mPendingEnableRollback. */
926 private int mPendingEnableRollbackToken = 0;
928 volatile boolean mSystemReady;
929 volatile boolean mSafeMode;
930 volatile boolean mHasSystemUidErrors;
931 private volatile SparseBooleanArray mWebInstantAppsDisabled = new SparseBooleanArray();
933 ApplicationInfo mAndroidApplication;
934 final ActivityInfo mResolveActivity = new ActivityInfo();
935 final ResolveInfo mResolveInfo = new ResolveInfo();
936 ComponentName mResolveComponentName;
937 PackageParser.Package mPlatformPackage;
938 ComponentName mCustomResolverComponentName;
940 boolean mResolverReplaced = false;
942 private final @Nullable ComponentName mIntentFilterVerifierComponent;
943 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
945 private int mIntentFilterVerificationToken = 0;
947 /** The service connection to the ephemeral resolver */
948 final InstantAppResolverConnection mInstantAppResolverConnection;
949 /** Component used to show resolver settings for Instant Apps */
950 final ComponentName mInstantAppResolverSettingsComponent;
952 /** Activity used to install instant applications */
953 ActivityInfo mInstantAppInstallerActivity;
954 final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
956 private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
957 mNoKillInstallObservers = Collections.synchronizedMap(new HashMap<>());
959 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
960 = new SparseArray<>();
962 // TODO remove this and go through mPermissonManager directly
963 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
964 private final PermissionManagerServiceInternal mPermissionManager;
966 private final ComponentResolver mComponentResolver;
967 // List of packages names to keep cached, even if they are uninstalled for all users
968 private List<String> mKeepUninstalledPackages;
970 private UserManagerInternal mUserManagerInternal;
971 private ActivityManagerInternal mActivityManagerInternal;
972 private ActivityTaskManagerInternal mActivityTaskManagerInternal;
973 private StorageManagerInternal mStorageManagerInternal;
975 private DeviceIdleController.LocalService mDeviceIdleController;
977 private File mCacheDir;
979 private Future<?> mPrepareAppDataFuture;
981 private static class IFVerificationParams {
982 PackageParser.Package pkg;
987 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
988 int _userId, int _verifierUid) {
990 replacing = _replacing;
992 verifierUid = _verifierUid;
996 private interface IntentFilterVerifier<T extends IntentFilter> {
997 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
998 T filter, String packageName);
999 void startVerifications(int userId);
1000 void receiveVerificationResponse(int verificationId);
1003 @GuardedBy("mPackages")
1004 private CheckPermissionDelegate mCheckPermissionDelegate;
1006 @GuardedBy("mPackages")
1007 private PackageManagerInternal.DefaultBrowserProvider mDefaultBrowserProvider;
1009 @GuardedBy("mPackages")
1010 private PackageManagerInternal.DefaultDialerProvider mDefaultDialerProvider;
1012 @GuardedBy("mPackages")
1013 private PackageManagerInternal.DefaultHomeProvider mDefaultHomeProvider;
1015 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1016 private Context mContext;
1017 private ComponentName mIntentFilterVerifierComponent;
1018 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<>();
1020 public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1022 mIntentFilterVerifierComponent = verifierComponent;
1025 private String getDefaultScheme() {
1026 return IntentFilter.SCHEME_HTTPS;
1030 public void startVerifications(int userId) {
1031 // Launch verifications requests
1032 int count = mCurrentIntentFilterVerifications.size();
1033 for (int n=0; n<count; n++) {
1034 int verificationId = mCurrentIntentFilterVerifications.get(n);
1035 final IntentFilterVerificationState ivs =
1036 mIntentFilterVerificationStates.get(verificationId);
1038 String packageName = ivs.getPackageName();
1040 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1041 final int filterCount = filters.size();
1042 ArraySet<String> domainsSet = new ArraySet<>();
1043 for (int m=0; m<filterCount; m++) {
1044 PackageParser.ActivityIntentInfo filter = filters.get(m);
1045 domainsSet.addAll(filter.getHostsList());
1047 synchronized (mPackages) {
1048 if (mSettings.createIntentFilterVerificationIfNeededLPw(
1049 packageName, domainsSet) != null) {
1050 scheduleWriteSettingsLocked();
1053 sendVerificationRequest(verificationId, ivs);
1055 mCurrentIntentFilterVerifications.clear();
1058 private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1059 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1060 verificationIntent.putExtra(
1061 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1063 verificationIntent.putExtra(
1064 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1065 getDefaultScheme());
1066 verificationIntent.putExtra(
1067 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1068 ivs.getHostsString());
1069 verificationIntent.putExtra(
1070 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1071 ivs.getPackageName());
1072 verificationIntent.setComponent(mIntentFilterVerifierComponent);
1073 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1075 final long whitelistTimeout = getVerificationTimeout();
1076 final BroadcastOptions options = BroadcastOptions.makeBasic();
1077 options.setTemporaryAppWhitelistDuration(whitelistTimeout);
1079 DeviceIdleController.LocalService idleController = getDeviceIdleController();
1080 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1081 mIntentFilterVerifierComponent.getPackageName(), whitelistTimeout,
1082 UserHandle.USER_SYSTEM, true, "intent filter verifier");
1084 mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM,
1085 null, options.toBundle());
1086 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1087 "Sending IntentFilter verification broadcast");
1090 public void receiveVerificationResponse(int verificationId) {
1091 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1093 final boolean verified = ivs.isVerified();
1095 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1096 final int count = filters.size();
1097 if (DEBUG_DOMAIN_VERIFICATION) {
1098 Slog.i(TAG, "Received verification response " + verificationId
1099 + " for " + count + " filters, verified=" + verified);
1101 for (int n=0; n<count; n++) {
1102 PackageParser.ActivityIntentInfo filter = filters.get(n);
1103 filter.setVerified(verified);
1105 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1106 + " verified with result:" + verified + " and hosts:"
1107 + ivs.getHostsString());
1110 mIntentFilterVerificationStates.remove(verificationId);
1112 final String packageName = ivs.getPackageName();
1113 IntentFilterVerificationInfo ivi;
1115 synchronized (mPackages) {
1116 ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1119 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1120 + verificationId + " packageName:" + packageName);
1124 synchronized (mPackages) {
1126 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1128 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1130 scheduleWriteSettingsLocked();
1132 final int userId = ivs.getUserId();
1133 if (userId != UserHandle.USER_ALL) {
1134 final int userStatus =
1135 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1137 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1138 boolean needUpdate = false;
1140 if (DEBUG_DOMAIN_VERIFICATION) {
1142 "Updating IntentFilterVerificationInfo for package " + packageName
1143 + " verificationId:" + verificationId
1144 + " verified=" + verified);
1147 // In a success case, we promote from undefined or ASK to ALWAYS. This
1148 // supports a flow where the app fails validation but then ships an updated
1149 // APK that passes, and therefore deserves to be in ALWAYS.
1151 // If validation failed, the undefined state winds up in the basic ASK behavior,
1152 // but apps that previously passed and became ALWAYS are *demoted* out of
1153 // that state, since they would not deserve the ALWAYS behavior in case of a
1155 switch (userStatus) {
1156 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
1158 // Don't demote if sysconfig says 'always'
1159 SystemConfig systemConfig = SystemConfig.getInstance();
1160 ArraySet<String> packages = systemConfig.getLinkedApps();
1161 if (!packages.contains(packageName)) {
1162 // updatedStatus is already UNDEFINED
1165 if (DEBUG_DOMAIN_VERIFICATION) {
1166 Slog.d(TAG, "Formerly validated but now failing; demoting");
1169 if (DEBUG_DOMAIN_VERIFICATION) {
1170 Slog.d(TAG, "Updating bundled package " + packageName
1171 + " failed autoVerify, but sysconfig supersedes");
1173 // leave needUpdate == false here intentionally
1178 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1179 // Stay in 'undefined' on verification failure
1181 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1184 if (DEBUG_DOMAIN_VERIFICATION) {
1185 Slog.d(TAG, "Applying update; old=" + userStatus
1186 + " new=" + updatedStatus);
1190 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1191 // Keep in 'ask' on failure
1193 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1203 mSettings.updateIntentFilterVerificationStatusLPw(
1204 packageName, updatedStatus, userId);
1205 scheduleWritePackageRestrictionsLocked(userId);
1208 Slog.i(TAG, "autoVerify ignored when installing for all users");
1214 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1215 ActivityIntentInfo filter, String packageName) {
1216 if (!hasValidDomains(filter)) {
1219 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1221 ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1224 if (DEBUG_DOMAIN_VERIFICATION) {
1225 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1227 ivs.addFilter(filter);
1231 private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1232 int userId, int verificationId, String packageName) {
1233 IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1234 verifierUid, userId, packageName);
1235 ivs.setPendingState();
1236 synchronized (mPackages) {
1237 mIntentFilterVerificationStates.append(verificationId, ivs);
1238 mCurrentIntentFilterVerifications.add(verificationId);
1244 private static boolean hasValidDomains(ActivityIntentInfo filter) {
1245 return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1246 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1247 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1250 // Set of pending broadcasts for aggregating enable/disable of components.
1251 static class PendingPackageBroadcasts {
1252 // for each user id, a map of <package name -> components within that package>
1253 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1255 public PendingPackageBroadcasts() {
1256 mUidMap = new SparseArray<>(2);
1259 public ArrayList<String> get(int userId, String packageName) {
1260 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1261 return packages.get(packageName);
1264 public void put(int userId, String packageName, ArrayList<String> components) {
1265 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1266 packages.put(packageName, components);
1269 public void remove(int userId, String packageName) {
1270 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1271 if (packages != null) {
1272 packages.remove(packageName);
1276 public void remove(int userId) {
1277 mUidMap.remove(userId);
1280 public int userIdCount() {
1281 return mUidMap.size();
1284 public int userIdAt(int n) {
1285 return mUidMap.keyAt(n);
1288 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1289 return mUidMap.get(userId);
1293 // total number of pending broadcast entries across all userIds
1295 for (int i = 0; i< mUidMap.size(); i++) {
1296 num += mUidMap.valueAt(i).size();
1301 public void clear() {
1305 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1306 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1308 map = new ArrayMap<>();
1309 mUidMap.put(userId, map);
1314 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1316 static final int SEND_PENDING_BROADCAST = 1;
1317 static final int INIT_COPY = 5;
1318 static final int POST_INSTALL = 9;
1319 static final int WRITE_SETTINGS = 13;
1320 static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1321 static final int PACKAGE_VERIFIED = 15;
1322 static final int CHECK_PENDING_VERIFICATION = 16;
1323 static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1324 static final int INTENT_FILTER_VERIFIED = 18;
1325 static final int WRITE_PACKAGE_LIST = 19;
1326 static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1327 static final int ENABLE_ROLLBACK_STATUS = 21;
1328 static final int ENABLE_ROLLBACK_TIMEOUT = 22;
1329 static final int DEFERRED_NO_KILL_POST_DELETE = 23;
1330 static final int DEFERRED_NO_KILL_INSTALL_OBSERVER = 24;
1332 static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
1333 static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
1335 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds
1337 private static final long BROADCAST_DELAY_DURING_STARTUP = 10 * 1000L; // 10 seconds (in millis)
1338 private static final long BROADCAST_DELAY = 1 * 1000L; // 1 second (in millis)
1340 // When the service constructor finished plus a delay (used for broadcast delay computation)
1341 private long mServiceStartWithDelay;
1343 private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1344 2 * 60 * 60 * 1000L; /* two hours */
1346 static UserManagerService sUserManager;
1348 // Stores a list of users whose package restrictions file needs to be updated
1349 private ArraySet<Integer> mDirtyUsers = new ArraySet<>();
1351 // Recordkeeping of restore-after-install operations that are currently in flight
1352 // between the Package Manager and the Backup Manager
1353 static class PostInstallData {
1354 public final InstallArgs args;
1355 public final PackageInstalledInfo res;
1356 public final Runnable mPostInstallRunnable;
1358 PostInstallData(InstallArgs _a, PackageInstalledInfo _r, Runnable postInstallRunnable) {
1361 mPostInstallRunnable = postInstallRunnable;
1365 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<>();
1366 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows
1368 // XML tags for backup/restore of various bits of state
1369 private static final String TAG_PREFERRED_BACKUP = "pa";
1370 private static final String TAG_DEFAULT_APPS = "da";
1371 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1373 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1374 private static final String TAG_ALL_GRANTS = "rt-grants";
1375 private static final String TAG_GRANT = "grant";
1376 private static final String ATTR_PACKAGE_NAME = "pkg";
1378 private static final String TAG_PERMISSION = "perm";
1379 private static final String ATTR_PERMISSION_NAME = "name";
1380 private static final String ATTR_IS_GRANTED = "g";
1381 private static final String ATTR_USER_SET = "set";
1382 private static final String ATTR_USER_FIXED = "fixed";
1383 private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1385 // System/policy permission grants are not backed up
1386 private static final int SYSTEM_RUNTIME_GRANT_MASK =
1387 FLAG_PERMISSION_POLICY_FIXED
1388 | FLAG_PERMISSION_SYSTEM_FIXED
1389 | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1391 // And we back up these user-adjusted states
1392 private static final int USER_RUNTIME_GRANT_MASK =
1393 FLAG_PERMISSION_USER_SET
1394 | FLAG_PERMISSION_USER_FIXED
1395 | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1397 final @Nullable String mRequiredVerifierPackage;
1398 final @NonNull String mRequiredInstallerPackage;
1399 final @NonNull String mRequiredUninstallerPackage;
1400 final @NonNull String mRequiredPermissionControllerPackage;
1401 final @Nullable String mSetupWizardPackage;
1402 final @Nullable String mStorageManagerPackage;
1403 final @Nullable String mSystemTextClassifierPackage;
1404 final @Nullable String mWellbeingPackage;
1405 final @Nullable String mDocumenterPackage;
1406 final @Nullable String mConfiguratorPackage;
1407 final @Nullable String mAppPredictionServicePackage;
1408 final @Nullable String mIncidentReportApproverPackage;
1409 final @NonNull String mServicesSystemSharedLibraryPackageName;
1410 final @NonNull String mSharedSystemSharedLibraryPackageName;
1412 private final PackageUsage mPackageUsage = new PackageUsage();
1413 private final CompilerStats mCompilerStats = new CompilerStats();
1415 class PackageHandler extends Handler {
1417 PackageHandler(Looper looper) {
1421 public void handleMessage(Message msg) {
1423 doHandleMessage(msg);
1425 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1429 void doHandleMessage(Message msg) {
1432 HandlerParams params = (HandlerParams) msg.obj;
1433 if (params != null) {
1434 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy: " + params);
1435 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1436 System.identityHashCode(params));
1437 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1439 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1443 case SEND_PENDING_BROADCAST: {
1445 ArrayList<String> components[];
1448 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1449 synchronized (mPackages) {
1450 size = mPendingBroadcasts.size();
1452 // Nothing to be done. Just return
1455 packages = new String[size];
1456 components = new ArrayList[size];
1457 uids = new int[size];
1458 int i = 0; // filling out the above arrays
1460 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1461 int packageUserId = mPendingBroadcasts.userIdAt(n);
1462 Iterator<Map.Entry<String, ArrayList<String>>> it
1463 = mPendingBroadcasts.packagesForUserId(packageUserId)
1464 .entrySet().iterator();
1465 while (it.hasNext() && i < size) {
1466 Map.Entry<String, ArrayList<String>> ent = it.next();
1467 packages[i] = ent.getKey();
1468 components[i] = ent.getValue();
1469 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1470 uids[i] = (ps != null)
1471 ? UserHandle.getUid(packageUserId, ps.appId)
1477 mPendingBroadcasts.clear();
1480 for (int i = 0; i < size; i++) {
1481 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1483 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1486 case POST_INSTALL: {
1487 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1489 PostInstallData data = mRunningInstalls.get(msg.arg1);
1490 final boolean didRestore = (msg.arg2 != 0);
1491 mRunningInstalls.delete(msg.arg1);
1493 if (data != null && data.mPostInstallRunnable != null) {
1494 data.mPostInstallRunnable.run();
1495 } else if (data != null) {
1496 InstallArgs args = data.args;
1497 PackageInstalledInfo parentRes = data.res;
1499 final boolean grantPermissions = (args.installFlags
1500 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1501 final boolean killApp = (args.installFlags
1502 & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1503 final boolean virtualPreload = ((args.installFlags
1504 & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1505 final String[] grantedPermissions = args.installGrantPermissions;
1506 final List<String> whitelistedRestrictedPermissions = ((args.installFlags
1507 & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0
1508 && parentRes.pkg != null)
1509 ? parentRes.pkg.requestedPermissions
1510 : args.whitelistedRestrictedPermissions;
1512 // Handle the parent package
1513 handlePackagePostInstall(parentRes, grantPermissions,
1514 killApp, virtualPreload, grantedPermissions,
1515 whitelistedRestrictedPermissions, didRestore,
1516 args.installerPackageName, args.observer);
1518 // Handle the child packages
1519 final int childCount = (parentRes.addedChildPackages != null)
1520 ? parentRes.addedChildPackages.size() : 0;
1521 for (int i = 0; i < childCount; i++) {
1522 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1523 handlePackagePostInstall(childRes, grantPermissions,
1524 killApp, virtualPreload, grantedPermissions,
1525 whitelistedRestrictedPermissions, false /*didRestore*/,
1526 args.installerPackageName, args.observer);
1529 // Log tracing if needed
1530 if (args.traceMethod != null) {
1531 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1534 } else if (DEBUG_INSTALL) {
1535 // No post-install when we run restore from installExistingPackageForUser
1536 Slog.i(TAG, "Nothing to do for post-install token " + msg.arg1);
1539 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1541 case DEFERRED_NO_KILL_POST_DELETE: {
1542 synchronized (mInstallLock) {
1543 InstallArgs args = (InstallArgs) msg.obj;
1545 args.doPostDeleteLI(true);
1549 case DEFERRED_NO_KILL_INSTALL_OBSERVER: {
1550 String packageName = (String) msg.obj;
1551 if (packageName != null) {
1552 notifyInstallObserver(packageName);
1555 case WRITE_SETTINGS: {
1556 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1557 synchronized (mPackages) {
1558 removeMessages(WRITE_SETTINGS);
1559 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1560 mSettings.writeLPr();
1561 mDirtyUsers.clear();
1563 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1565 case WRITE_PACKAGE_RESTRICTIONS: {
1566 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1567 synchronized (mPackages) {
1568 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1569 for (int userId : mDirtyUsers) {
1570 mSettings.writePackageRestrictionsLPr(userId);
1572 mDirtyUsers.clear();
1574 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1576 case WRITE_PACKAGE_LIST: {
1577 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1578 synchronized (mPackages) {
1579 removeMessages(WRITE_PACKAGE_LIST);
1580 mSettings.writePackageListLPr(msg.arg1);
1582 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1584 case CHECK_PENDING_VERIFICATION: {
1585 final int verificationId = msg.arg1;
1586 final PackageVerificationState state = mPendingVerification.get(verificationId);
1588 if ((state != null) && !state.timeoutExtended()) {
1589 final InstallParams params = state.getInstallParams();
1590 final InstallArgs args = params.mArgs;
1591 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1593 Slog.i(TAG, "Verification timed out for " + originUri);
1594 mPendingVerification.remove(verificationId);
1596 final UserHandle user = args.getUser();
1597 if (getDefaultVerificationResponse(user)
1598 == PackageManager.VERIFICATION_ALLOW) {
1599 Slog.i(TAG, "Continuing with installation of " + originUri);
1600 state.setVerifierResponse(Binder.getCallingUid(),
1601 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1602 broadcastPackageVerified(verificationId, originUri,
1603 PackageManager.VERIFICATION_ALLOW, user);
1605 broadcastPackageVerified(verificationId, originUri,
1606 PackageManager.VERIFICATION_REJECT, user);
1607 params.setReturnCode(
1608 PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
1611 Trace.asyncTraceEnd(
1612 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1613 params.handleVerificationFinished();
1617 case PACKAGE_VERIFIED: {
1618 final int verificationId = msg.arg1;
1620 final PackageVerificationState state = mPendingVerification.get(verificationId);
1621 if (state == null) {
1622 Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1626 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1628 state.setVerifierResponse(response.callerUid, response.code);
1630 if (state.isVerificationComplete()) {
1631 mPendingVerification.remove(verificationId);
1633 final InstallParams params = state.getInstallParams();
1634 final InstallArgs args = params.mArgs;
1635 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1637 if (state.isInstallAllowed()) {
1638 broadcastPackageVerified(verificationId, originUri,
1639 response.code, args.getUser());
1641 params.setReturnCode(
1642 PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
1645 Trace.asyncTraceEnd(
1646 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1648 params.handleVerificationFinished();
1653 case START_INTENT_FILTER_VERIFICATIONS: {
1654 IFVerificationParams params = (IFVerificationParams) msg.obj;
1655 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1656 params.replacing, params.pkg);
1659 case INTENT_FILTER_VERIFIED: {
1660 final int verificationId = msg.arg1;
1662 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1664 if (state == null) {
1665 Slog.w(TAG, "Invalid IntentFilter verification token "
1666 + verificationId + " received");
1670 final int userId = state.getUserId();
1672 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1673 "Processing IntentFilter verification with token:"
1674 + verificationId + " and userId:" + userId);
1676 final IntentFilterVerificationResponse response =
1677 (IntentFilterVerificationResponse) msg.obj;
1679 state.setVerifierResponse(response.callerUid, response.code);
1681 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1682 "IntentFilter verification with token:" + verificationId
1683 + " and userId:" + userId
1684 + " is settings verifier response with response code:"
1687 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1688 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1689 + response.getFailedDomainsString());
1692 if (state.isVerificationComplete()) {
1693 mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1695 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1696 "IntentFilter verification with token:" + verificationId
1697 + " was not said to be complete");
1702 case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1703 InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1704 mInstantAppResolverConnection,
1705 (InstantAppRequest) msg.obj,
1706 mInstantAppInstallerActivity,
1710 case ENABLE_ROLLBACK_STATUS: {
1711 final int enableRollbackToken = msg.arg1;
1712 final int enableRollbackCode = msg.arg2;
1713 InstallParams params = mPendingEnableRollback.get(enableRollbackToken);
1714 if (params == null) {
1715 Slog.w(TAG, "Invalid rollback enabled token "
1716 + enableRollbackToken + " received");
1720 mPendingEnableRollback.remove(enableRollbackToken);
1722 if (enableRollbackCode != PackageManagerInternal.ENABLE_ROLLBACK_SUCCEEDED) {
1723 final InstallArgs args = params.mArgs;
1724 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1725 Slog.w(TAG, "Failed to enable rollback for " + originUri);
1726 Slog.w(TAG, "Continuing with installation of " + originUri);
1729 Trace.asyncTraceEnd(
1730 TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
1732 params.handleRollbackEnabled();
1735 case ENABLE_ROLLBACK_TIMEOUT: {
1736 final int enableRollbackToken = msg.arg1;
1737 final InstallParams params = mPendingEnableRollback.get(enableRollbackToken);
1738 if (params != null) {
1739 final InstallArgs args = params.mArgs;
1740 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1742 Slog.w(TAG, "Enable rollback timed out for " + originUri);
1743 mPendingEnableRollback.remove(enableRollbackToken);
1745 Slog.w(TAG, "Continuing with installation of " + originUri);
1746 Trace.asyncTraceEnd(
1747 TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
1748 params.handleRollbackEnabled();
1749 Intent rollbackTimeoutIntent = new Intent(
1750 Intent.ACTION_CANCEL_ENABLE_ROLLBACK);
1751 rollbackTimeoutIntent.putExtra(
1752 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN,
1753 enableRollbackToken);
1754 rollbackTimeoutIntent.addFlags(
1755 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1756 mContext.sendBroadcastAsUser(rollbackTimeoutIntent, UserHandle.SYSTEM,
1757 android.Manifest.permission.PACKAGE_ROLLBACK_AGENT);
1765 private PermissionCallback mPermissionCallback = new PermissionCallback() {
1767 public void onGidsChanged(int appId, int userId) {
1768 mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED));
1771 public void onPermissionGranted(int uid, int userId) {
1772 mOnPermissionChangeListeners.onPermissionsChanged(uid);
1774 // Not critical; if this is lost, the application has to request again.
1775 synchronized (mPackages) {
1776 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
1780 public void onInstallPermissionGranted() {
1781 synchronized (mPackages) {
1782 scheduleWriteSettingsLocked();
1786 public void onPermissionRevoked(int uid, int userId) {
1787 mOnPermissionChangeListeners.onPermissionsChanged(uid);
1789 synchronized (mPackages) {
1790 // Critical; after this call the application should never have the permission
1791 mSettings.writeRuntimePermissionsForUserLPr(userId, true);
1794 final int appId = UserHandle.getAppId(uid);
1795 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
1798 public void onInstallPermissionRevoked() {
1799 synchronized (mPackages) {
1800 scheduleWriteSettingsLocked();
1804 public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
1805 synchronized (mPackages) {
1806 for (int userId : updatedUserIds) {
1807 mSettings.writeRuntimePermissionsForUserLPr(userId, sync);
1812 public void onInstallPermissionUpdated() {
1813 synchronized (mPackages) {
1814 scheduleWriteSettingsLocked();
1818 public void onPermissionRemoved() {
1819 synchronized (mPackages) {
1820 mSettings.writeLPr();
1825 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1826 boolean killApp, boolean virtualPreload,
1827 String[] grantedPermissions, List<String> whitelistedRestrictedPermissions,
1828 boolean launchedForRestore, String installerPackage,
1829 IPackageInstallObserver2 installObserver) {
1830 final boolean succeeded = res.returnCode == PackageManager.INSTALL_SUCCEEDED;
1831 final boolean update = res.removedInfo != null && res.removedInfo.removedPackage != null;
1834 // Send the removed broadcasts
1835 if (res.removedInfo != null) {
1836 res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1839 // Whitelist any restricted permissions first as some may be runtime
1840 // that the installer requested to be granted at install time.
1841 if (whitelistedRestrictedPermissions != null
1842 && !whitelistedRestrictedPermissions.isEmpty()) {
1843 mPermissionManager.setWhitelistedRestrictedPermissions(
1844 res.pkg, res.newUsers, whitelistedRestrictedPermissions,
1845 Process.myUid(), PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER,
1846 mPermissionCallback);
1849 // Now that we successfully installed the package, grant runtime
1850 // permissions if requested before broadcasting the install. Also
1851 // for legacy apps in permission review mode we clear the permission
1852 // review flag which is used to emulate runtime permissions for
1854 if (grantPermissions) {
1855 final int callingUid = Binder.getCallingUid();
1856 mPermissionManager.grantRequestedRuntimePermissions(
1857 res.pkg, res.newUsers, grantedPermissions, callingUid,
1858 mPermissionCallback);
1861 final String installerPackageName =
1862 res.installerPackageName != null
1863 ? res.installerPackageName
1864 : res.removedInfo != null
1865 ? res.removedInfo.installerPackageName
1868 // If this is the first time we have child packages for a disabled privileged
1869 // app that had no children, we grant requested runtime permissions to the new
1870 // children if the parent on the system image had them already granted.
1871 if (res.pkg.parentPackage != null) {
1872 final int callingUid = Binder.getCallingUid();
1873 mPermissionManager.grantRuntimePermissionsGrantedToDisabledPackage(
1874 res.pkg, callingUid, mPermissionCallback);
1877 synchronized (mPackages) {
1878 mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1881 final String packageName = res.pkg.applicationInfo.packageName;
1883 // Determine the set of users who are adding this package for
1884 // the first time vs. those who are seeing an update.
1885 int[] firstUserIds = EMPTY_INT_ARRAY;
1886 int[] firstInstantUserIds = EMPTY_INT_ARRAY;
1887 int[] updateUserIds = EMPTY_INT_ARRAY;
1888 int[] instantUserIds = EMPTY_INT_ARRAY;
1889 final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1890 final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1891 for (int newUser : res.newUsers) {
1892 final boolean isInstantApp = ps.getInstantApp(newUser);
1895 firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
1897 firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
1901 boolean isNew = true;
1902 for (int origUser : res.origUsers) {
1903 if (origUser == newUser) {
1910 firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
1912 firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
1916 instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
1918 updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
1923 // Send installed broadcasts if the package is not a static shared lib.
1924 if (res.pkg.staticSharedLibName == null) {
1925 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1927 // Send added for users that see the package for the first time
1928 // sendPackageAddedForNewUsers also deals with system apps
1929 int appId = UserHandle.getAppId(res.uid);
1930 boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1931 sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
1932 virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds);
1934 // Send added for users that don't see the package for the first time
1935 Bundle extras = new Bundle(1);
1936 extras.putInt(Intent.EXTRA_UID, res.uid);
1938 extras.putBoolean(Intent.EXTRA_REPLACING, true);
1940 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1941 extras, 0 /*flags*/,
1942 null /*targetPackage*/, null /*finishedReceiver*/,
1943 updateUserIds, instantUserIds);
1944 if (installerPackageName != null) {
1945 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1946 extras, 0 /*flags*/,
1947 installerPackageName, null /*finishedReceiver*/,
1948 updateUserIds, instantUserIds);
1950 // if the required verifier is defined, but, is not the installer of record
1951 // for the package, it gets notified
1952 final boolean notifyVerifier = mRequiredVerifierPackage != null
1953 && !mRequiredVerifierPackage.equals(installerPackageName);
1954 if (notifyVerifier) {
1955 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1956 extras, 0 /*flags*/,
1957 mRequiredVerifierPackage, null /*finishedReceiver*/,
1958 updateUserIds, instantUserIds);
1960 // If package installer is defined, notify package installer about new
1962 if (mRequiredInstallerPackage != null) {
1963 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1964 extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND /*flags*/,
1965 mRequiredInstallerPackage, null /*finishedReceiver*/,
1966 firstUserIds, instantUserIds);
1969 // Send replaced for users that don't see the package for the first time
1971 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1972 packageName, extras, 0 /*flags*/,
1973 null /*targetPackage*/, null /*finishedReceiver*/,
1974 updateUserIds, instantUserIds);
1975 if (installerPackageName != null) {
1976 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
1977 extras, 0 /*flags*/,
1978 installerPackageName, null /*finishedReceiver*/,
1979 updateUserIds, instantUserIds);
1981 if (notifyVerifier) {
1982 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
1983 extras, 0 /*flags*/,
1984 mRequiredVerifierPackage, null /*finishedReceiver*/,
1985 updateUserIds, instantUserIds);
1987 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1988 null /*package*/, null /*extras*/, 0 /*flags*/,
1989 packageName /*targetPackage*/,
1990 null /*finishedReceiver*/, updateUserIds, instantUserIds);
1991 } else if (launchedForRestore && !isSystemApp(res.pkg)) {
1992 // First-install and we did a restore, so we're responsible for the
1993 // first-launch broadcast.
1995 Slog.i(TAG, "Post-restore of " + packageName
1996 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds));
1998 sendFirstLaunchBroadcast(packageName, installerPackage,
1999 firstUserIds, firstInstantUserIds);
2002 // Send broadcast package appeared if external for all users
2003 if (isExternal(res.pkg)) {
2005 final StorageManager storage =
2006 mContext.getSystemService(StorageManager.class);
2008 storage.findVolumeByUuid(
2009 res.pkg.applicationInfo.storageUuid.toString());
2010 int packageExternalStorageType =
2011 getPackageExternalStorageType(volume, isExternal(res.pkg));
2012 // If the package was installed externally, log it.
2013 if (packageExternalStorageType != StorageEnums.UNKNOWN) {
2014 StatsLog.write(StatsLog.APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED,
2015 packageExternalStorageType, res.pkg.packageName);
2018 if (DEBUG_INSTALL) {
2019 Slog.i(TAG, "upgrading pkg " + res.pkg + " is external");
2021 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2022 ArrayList<String> pkgList = new ArrayList<>(1);
2023 pkgList.add(packageName);
2024 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2028 // Work that needs to happen on first install within each user
2029 if (firstUserIds != null && firstUserIds.length > 0) {
2030 for (int userId : firstUserIds) {
2031 // If this app is a browser and it's newly-installed for some
2032 // users, clear any default-browser state in those users. The
2033 // app's nature doesn't depend on the user, so we can just check
2034 // its browser nature in any user and generalize.
2035 if (packageIsBrowser(packageName, userId)) {
2036 // If this browser is restored from user's backup, do not clear
2037 // default-browser state for this user
2038 synchronized (mPackages) {
2039 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
2040 if (pkgSetting.getInstallReason(userId)
2041 != PackageManager.INSTALL_REASON_DEVICE_RESTORE) {
2042 setDefaultBrowserAsyncLPw(null, userId);
2047 // We may also need to apply pending (restored) runtime permission grants
2048 // within these users.
2049 mPermissionManager.restoreDelayedRuntimePermissions(packageName,
2050 UserHandle.of(userId));
2052 // Persistent preferred activity might have came into effect due to this
2054 updateDefaultHomeNotLocked(userId);
2058 if (allNewUsers && !update) {
2059 notifyPackageAdded(packageName, res.uid);
2061 notifyPackageChanged(packageName, res.uid);
2064 // Log current value of "unknown sources" setting
2065 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2066 getUnknownSourcesSettings());
2068 // Remove the replaced package's older resources safely now
2069 InstallArgs args = res.removedInfo != null ? res.removedInfo.args : null;
2072 // If we didn't kill the app, defer the deletion of code/resource files, since
2073 // they may still be in use by the running application. This mitigates problems
2074 // in cases where resources or code is loaded by a new Activity before
2075 // ApplicationInfo changes have propagated to all application threads.
2076 scheduleDeferredNoKillPostDelete(args);
2078 synchronized (mInstallLock) {
2079 args.doPostDeleteLI(true);
2083 // Force a gc to clear up things. Ask for a background one, it's fine to go on
2084 // and not block here.
2085 VMRuntime.getRuntime().requestConcurrentGC();
2088 // Notify DexManager that the package was installed for new users.
2089 // The updated users should already be indexed and the package code paths
2090 // should not change.
2091 // Don't notify the manager for ephemeral apps as they are not expected to
2092 // survive long enough to benefit of background optimizations.
2093 for (int userId : firstUserIds) {
2094 PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2095 // There's a race currently where some install events may interleave with an uninstall.
2096 // This can lead to package info being null (b/36642664).
2098 mDexManager.notifyPackageInstalled(info, userId);
2103 final boolean deferInstallObserver = succeeded && update && !killApp;
2104 if (deferInstallObserver) {
2105 scheduleDeferredNoKillInstallObserver(res, installObserver);
2107 notifyInstallObserver(res, installObserver);
2112 public void notifyPackagesReplacedReceived(String[] packages) {
2113 final int callingUid = Binder.getCallingUid();
2114 final int callingUserId = UserHandle.getUserId(callingUid);
2116 for (String packageName : packages) {
2117 PackageSetting setting = mSettings.mPackages.get(packageName);
2118 if (setting != null && filterAppAccessLPr(setting, callingUid, callingUserId)) {
2119 notifyInstallObserver(packageName);
2124 private void notifyInstallObserver(String packageName) {
2125 Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
2126 mNoKillInstallObservers.remove(packageName);
2129 notifyInstallObserver(pair.first, pair.second);
2133 private void notifyInstallObserver(PackageInstalledInfo info,
2134 IPackageInstallObserver2 installObserver) {
2135 if (installObserver != null) {
2137 Bundle extras = extrasForInstallResult(info);
2138 installObserver.onPackageInstalled(info.name, info.returnCode,
2139 info.returnMsg, extras);
2140 } catch (RemoteException e) {
2141 Slog.i(TAG, "Observer no longer exists.");
2146 private void scheduleDeferredNoKillPostDelete(InstallArgs args) {
2147 Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_POST_DELETE, args);
2148 mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_POST_DELETE_DELAY_MS);
2151 private void scheduleDeferredNoKillInstallObserver(PackageInstalledInfo info,
2152 IPackageInstallObserver2 observer) {
2153 String packageName = info.pkg.packageName;
2154 mNoKillInstallObservers.put(packageName, Pair.create(info, observer));
2155 Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_INSTALL_OBSERVER, packageName);
2156 mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS);
2160 * Gets the type of the external storage a package is installed on.
2161 * @param packageVolume The storage volume of the package.
2162 * @param packageIsExternal true if the package is currently installed on
2163 * external/removable/unprotected storage.
2164 * @return {@link StorageEnum#TYPE_UNKNOWN} if the package is not stored externally or the
2165 * corresponding {@link StorageEnum} storage type value if it is.
2167 private static int getPackageExternalStorageType(VolumeInfo packageVolume,
2168 boolean packageIsExternal) {
2169 if (packageVolume != null) {
2170 DiskInfo disk = packageVolume.getDisk();
2173 return StorageEnums.SD_CARD;
2176 return StorageEnums.USB;
2178 if (packageIsExternal) {
2179 return StorageEnums.OTHER;
2183 return StorageEnums.UNKNOWN;
2186 private StorageEventListener mStorageListener = new StorageEventListener() {
2188 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2189 if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2190 if (vol.state == VolumeInfo.STATE_MOUNTED) {
2191 final String volumeUuid = vol.getFsUuid();
2193 // Clean up any users or apps that were removed or recreated
2194 // while this volume was missing
2195 sUserManager.reconcileUsers(volumeUuid);
2196 reconcileApps(volumeUuid);
2198 // Clean up any install sessions that expired or were
2199 // cancelled while this volume was missing
2200 mInstallerService.onPrivateVolumeMounted(volumeUuid);
2202 loadPrivatePackages(vol);
2204 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2205 unloadPrivatePackages(vol);
2211 public void onVolumeForgotten(String fsUuid) {
2212 if (TextUtils.isEmpty(fsUuid)) {
2213 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2217 // Remove any apps installed on the forgotten volume
2218 synchronized (mPackages) {
2219 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2220 for (PackageSetting ps : packages) {
2221 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2222 deletePackageVersioned(new VersionedPackage(ps.name,
2223 PackageManager.VERSION_CODE_HIGHEST),
2224 new LegacyPackageDeleteObserver(null).getBinder(),
2225 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2226 // Try very hard to release any references to this package
2227 // so we don't risk the system server being killed due to
2229 AttributeCache.instance().removePackage(ps.name);
2232 mSettings.onVolumeForgotten(fsUuid);
2233 mSettings.writeLPr();
2238 Bundle extrasForInstallResult(PackageInstalledInfo res) {
2239 Bundle extras = null;
2240 switch (res.returnCode) {
2241 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2242 extras = new Bundle();
2243 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2244 res.origPermission);
2245 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2249 case PackageManager.INSTALL_SUCCEEDED: {
2250 extras = new Bundle();
2251 extras.putBoolean(Intent.EXTRA_REPLACING,
2252 res.removedInfo != null && res.removedInfo.removedPackage != null);
2259 void scheduleWriteSettingsLocked() {
2260 if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2261 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2265 void scheduleWritePackageListLocked(int userId) {
2266 if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2267 Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2269 mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2273 void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2274 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2275 scheduleWritePackageRestrictionsLocked(userId);
2278 void scheduleWritePackageRestrictionsLocked(int userId) {
2279 final int[] userIds = (userId == UserHandle.USER_ALL)
2280 ? sUserManager.getUserIds() : new int[]{userId};
2281 for (int nextUserId : userIds) {
2282 if (!sUserManager.exists(nextUserId)) return;
2283 mDirtyUsers.add(nextUserId);
2284 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2285 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2290 public static PackageManagerService main(Context context, Installer installer,
2291 boolean factoryTest, boolean onlyCore) {
2292 // Self-check for initial settings.
2293 PackageManagerServiceCompilerMapping.checkProperties();
2295 PackageManagerService m = new PackageManagerService(context, installer,
2296 factoryTest, onlyCore);
2297 m.enableSystemUserPackages();
2298 ServiceManager.addService("package", m);
2299 final PackageManagerNative pmn = m.new PackageManagerNative();
2300 ServiceManager.addService("package_native", pmn);
2304 private void enableSystemUserPackages() {
2305 if (!UserManager.isSplitSystemUser()) {
2308 // For system user, enable apps based on the following conditions:
2309 // - app is whitelisted or belong to one of these groups:
2310 // -- system app which has no launcher icons
2311 // -- system app which has INTERACT_ACROSS_USERS permission
2312 // -- system IME app
2313 // - app is not in the blacklist
2314 AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2315 Set<String> enableApps = new ArraySet<>();
2316 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2317 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2318 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2319 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2320 enableApps.addAll(wlApps);
2321 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2322 /* systemAppsOnly */ false, UserHandle.SYSTEM));
2323 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2324 enableApps.removeAll(blApps);
2325 Log.i(TAG, "Applications installed for system user: " + enableApps);
2326 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2328 final int allAppsSize = allAps.size();
2329 synchronized (mPackages) {
2330 for (int i = 0; i < allAppsSize; i++) {
2331 String pName = allAps.get(i);
2332 PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2333 // Should not happen, but we shouldn't be failing if it does
2334 if (pkgSetting == null) {
2337 boolean install = enableApps.contains(pName);
2338 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2339 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2340 + " for system user");
2341 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2344 scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2348 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2349 DisplayManager displayManager = (DisplayManager) context.getSystemService(
2350 Context.DISPLAY_SERVICE);
2351 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2355 * Requests that files preopted on a secondary system partition be copied to the data partition
2356 * if possible. Note that the actual copying of the files is accomplished by init for security
2357 * reasons. This simply requests that the copy takes place and awaits confirmation of its
2358 * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2360 private static void requestCopyPreoptedFiles() {
2361 final int WAIT_TIME_MS = 100;
2362 final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2363 if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2364 SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2365 // We will wait for up to 100 seconds.
2366 final long timeStart = SystemClock.uptimeMillis();
2367 final long timeEnd = timeStart + 100 * 1000;
2368 long timeNow = timeStart;
2369 while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2371 Thread.sleep(WAIT_TIME_MS);
2372 } catch (InterruptedException e) {
2375 timeNow = SystemClock.uptimeMillis();
2376 if (timeNow > timeEnd) {
2377 SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2378 Slog.wtf(TAG, "cppreopt did not finish!");
2383 Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2387 public PackageManagerService(Context context, Installer installer,
2388 boolean factoryTest, boolean onlyCore) {
2389 LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2390 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2391 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2392 SystemClock.uptimeMillis());
2394 if (mSdkVersion <= 0) {
2395 Slog.w(TAG, "**** ro.build.version.sdk not set!");
2400 mFactoryTest = factoryTest;
2401 mOnlyCore = onlyCore;
2402 mMetrics = new DisplayMetrics();
2403 mInstaller = installer;
2405 // Create sub-components that provide services / data. Order here is important.
2406 synchronized (mInstallLock) {
2407 synchronized (mPackages) {
2408 // Expose private service for system components to use.
2409 LocalServices.addService(
2410 PackageManagerInternal.class, new PackageManagerInternalImpl());
2411 sUserManager = new UserManagerService(context, this,
2412 new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2413 mComponentResolver = new ComponentResolver(sUserManager,
2414 LocalServices.getService(PackageManagerInternal.class),
2416 mPermissionManager = PermissionManagerService.create(context,
2417 mPackages /*externalLock*/);
2418 mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
2419 mSettings = new Settings(Environment.getDataDirectory(),
2420 mPermissionManager.getPermissionSettings(), mPackages);
2423 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2424 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2425 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2426 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2427 mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2428 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2429 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2430 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2431 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2432 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2433 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2434 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2435 mSettings.addSharedUserLPw("android.uid.se", SE_UID,
2436 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2437 mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID,
2438 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2440 String separateProcesses = SystemProperties.get("debug.separate_processes");
2441 if (separateProcesses != null && separateProcesses.length() > 0) {
2442 if ("*".equals(separateProcesses)) {
2443 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2444 mSeparateProcesses = null;
2445 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2448 mSeparateProcesses = separateProcesses.split(",");
2449 Slog.w(TAG, "Running with debug.separate_processes: "
2450 + separateProcesses);
2454 mSeparateProcesses = null;
2457 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2459 mDexManager = new DexManager(mContext, this, mPackageDexOptimizer, installer, mInstallLock);
2460 mArtManagerService = new ArtManagerService(mContext, this, installer, mInstallLock);
2461 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2463 mViewCompiler = new ViewCompiler(mInstallLock, mInstaller);
2465 mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2466 FgThread.get().getLooper());
2468 getDefaultDisplayMetrics(context, mMetrics);
2470 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2471 SystemConfig systemConfig = SystemConfig.getInstance();
2472 mAvailableFeatures = systemConfig.getAvailableFeatures();
2473 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2475 mProtectedPackages = new ProtectedPackages(mContext);
2477 mApexManager = new ApexManager(context);
2478 synchronized (mInstallLock) {
2480 synchronized (mPackages) {
2481 mHandlerThread = new ServiceThread(TAG,
2482 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2483 mHandlerThread.start();
2484 mHandler = new PackageHandler(mHandlerThread.getLooper());
2485 mProcessLoggingHandler = new ProcessLoggingHandler();
2486 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2487 mInstantAppRegistry = new InstantAppRegistry(this);
2489 ArrayMap<String, SystemConfig.SharedLibraryEntry> libConfig
2490 = systemConfig.getSharedLibraries();
2491 final int builtInLibCount = libConfig.size();
2492 for (int i = 0; i < builtInLibCount; i++) {
2493 String name = libConfig.keyAt(i);
2494 SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
2495 addBuiltInSharedLibraryLocked(entry.filename, name);
2498 // Now that we have added all the libraries, iterate again to add dependency
2499 // information IFF their dependencies are added.
2500 long undefinedVersion = SharedLibraryInfo.VERSION_UNDEFINED;
2501 for (int i = 0; i < builtInLibCount; i++) {
2502 String name = libConfig.keyAt(i);
2503 SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
2504 final int dependencyCount = entry.dependencies.length;
2505 for (int j = 0; j < dependencyCount; j++) {
2506 final SharedLibraryInfo dependency =
2507 getSharedLibraryInfoLPr(entry.dependencies[j], undefinedVersion);
2508 if (dependency != null) {
2509 getSharedLibraryInfoLPr(name, undefinedVersion).addDependency(dependency);
2514 SELinuxMMAC.readInstallPolicy();
2516 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
2517 FallbackCategoryProvider.loadFallbacks();
2518 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2520 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2521 mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2522 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2524 // Clean up orphaned packages for which the code path doesn't exist
2525 // and they are an update to a system app - caused by bug/32321269
2526 final int packageSettingCount = mSettings.mPackages.size();
2527 for (int i = packageSettingCount - 1; i >= 0; i--) {
2528 PackageSetting ps = mSettings.mPackages.valueAt(i);
2529 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2530 && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2531 mSettings.mPackages.removeAt(i);
2532 mSettings.enableSystemPackageLPw(ps.name);
2536 if (!mOnlyCore && mFirstBoot) {
2537 requestCopyPreoptedFiles();
2540 String customResolverActivityName = Resources.getSystem().getString(
2541 R.string.config_customResolverActivity);
2542 if (!TextUtils.isEmpty(customResolverActivityName)) {
2543 mCustomResolverComponentName = ComponentName.unflattenFromString(
2544 customResolverActivityName);
2547 long startTime = SystemClock.uptimeMillis();
2549 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2552 final String bootClassPath = System.getenv("BOOTCLASSPATH");
2553 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2555 if (bootClassPath == null) {
2556 Slog.w(TAG, "No BOOTCLASSPATH found!");
2559 if (systemServerClassPath == null) {
2560 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2563 File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2565 final VersionInfo ver = mSettings.getInternalVersion();
2566 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2568 logCriticalInfo(Log.INFO,
2569 "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2572 // when upgrading from pre-M, promote system app permissions from install to runtime
2573 mPromoteSystemApps =
2574 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2576 // When upgrading from pre-N, we need to handle package extraction like first boot,
2577 // as there is no profiling data available.
2578 mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2580 mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2581 mIsPreQUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.Q;
2583 int preUpgradeSdkVersion = ver.sdkVersion;
2585 // save off the names of pre-existing system packages prior to scanning; we don't
2586 // want to automatically grant runtime permissions for new system apps
2587 if (mPromoteSystemApps) {
2588 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2589 while (pkgSettingIter.hasNext()) {
2590 PackageSetting ps = pkgSettingIter.next();
2591 if (isSystemApp(ps)) {
2592 mExistingSystemPackages.add(ps.name);
2597 mCacheDir = preparePackageParserCache();
2599 // Set flag to monitor and not change apk file paths when
2600 // scanning install directories.
2601 int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2603 if (mIsUpgrade || mFirstBoot) {
2604 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2607 // Collect vendor/product/product_services overlay packages. (Do this before scanning
2609 // For security and version matching reason, only consider overlay packages if they
2610 // reside in the right directory.
2611 scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
2613 | PackageParser.PARSE_IS_SYSTEM_DIR,
2618 scanDirTracedLI(new File(PRODUCT_OVERLAY_DIR),
2620 | PackageParser.PARSE_IS_SYSTEM_DIR,
2625 scanDirTracedLI(new File(PRODUCT_SERVICES_OVERLAY_DIR),
2627 | PackageParser.PARSE_IS_SYSTEM_DIR,
2630 | SCAN_AS_PRODUCT_SERVICES,
2632 scanDirTracedLI(new File(ODM_OVERLAY_DIR),
2634 | PackageParser.PARSE_IS_SYSTEM_DIR,
2639 scanDirTracedLI(new File(OEM_OVERLAY_DIR),
2641 | PackageParser.PARSE_IS_SYSTEM_DIR,
2647 mParallelPackageParserCallback.findStaticOverlayPackages();
2649 // Find base frameworks (resource packages without code).
2650 scanDirTracedLI(frameworkDir,
2652 | PackageParser.PARSE_IS_SYSTEM_DIR,
2656 | SCAN_AS_PRIVILEGED,
2658 if (!mPackages.containsKey("android")) {
2659 throw new IllegalStateException(
2660 "Failed to load frameworks package; check log for warnings");
2663 // Collect privileged system packages.
2664 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2665 scanDirTracedLI(privilegedAppDir,
2667 | PackageParser.PARSE_IS_SYSTEM_DIR,
2670 | SCAN_AS_PRIVILEGED,
2673 // Collect ordinary system packages.
2674 final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2675 scanDirTracedLI(systemAppDir,
2677 | PackageParser.PARSE_IS_SYSTEM_DIR,
2682 // Collect privileged vendor packages.
2683 File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
2685 privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
2686 } catch (IOException e) {
2687 // failed to look up canonical path, continue with original one
2689 scanDirTracedLI(privilegedVendorAppDir,
2691 | PackageParser.PARSE_IS_SYSTEM_DIR,
2695 | SCAN_AS_PRIVILEGED,
2698 // Collect ordinary vendor packages.
2699 File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
2701 vendorAppDir = vendorAppDir.getCanonicalFile();
2702 } catch (IOException e) {
2703 // failed to look up canonical path, continue with original one
2705 scanDirTracedLI(vendorAppDir,
2707 | PackageParser.PARSE_IS_SYSTEM_DIR,
2713 // Collect privileged odm packages. /odm is another vendor partition
2714 // other than /vendor.
2715 File privilegedOdmAppDir = new File(Environment.getOdmDirectory(),
2718 privilegedOdmAppDir = privilegedOdmAppDir.getCanonicalFile();
2719 } catch (IOException e) {
2720 // failed to look up canonical path, continue with original one
2722 scanDirTracedLI(privilegedOdmAppDir,
2724 | PackageParser.PARSE_IS_SYSTEM_DIR,
2728 | SCAN_AS_PRIVILEGED,
2731 // Collect ordinary odm packages. /odm is another vendor partition
2732 // other than /vendor.
2733 File odmAppDir = new File(Environment.getOdmDirectory(), "app");
2735 odmAppDir = odmAppDir.getCanonicalFile();
2736 } catch (IOException e) {
2737 // failed to look up canonical path, continue with original one
2739 scanDirTracedLI(odmAppDir,
2741 | PackageParser.PARSE_IS_SYSTEM_DIR,
2747 // Collect all OEM packages.
2748 final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2749 scanDirTracedLI(oemAppDir,
2751 | PackageParser.PARSE_IS_SYSTEM_DIR,
2757 // Collected privileged /product packages.
2758 File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
2760 privilegedProductAppDir = privilegedProductAppDir.getCanonicalFile();
2761 } catch (IOException e) {
2762 // failed to look up canonical path, continue with original one
2764 scanDirTracedLI(privilegedProductAppDir,
2766 | PackageParser.PARSE_IS_SYSTEM_DIR,
2770 | SCAN_AS_PRIVILEGED,
2773 // Collect ordinary /product packages.
2774 File productAppDir = new File(Environment.getProductDirectory(), "app");
2776 productAppDir = productAppDir.getCanonicalFile();
2777 } catch (IOException e) {
2778 // failed to look up canonical path, continue with original one
2780 scanDirTracedLI(productAppDir,
2782 | PackageParser.PARSE_IS_SYSTEM_DIR,
2788 // Collected privileged /product_services packages.
2789 File privilegedProductServicesAppDir =
2790 new File(Environment.getProductServicesDirectory(), "priv-app");
2792 privilegedProductServicesAppDir =
2793 privilegedProductServicesAppDir.getCanonicalFile();
2794 } catch (IOException e) {
2795 // failed to look up canonical path, continue with original one
2797 scanDirTracedLI(privilegedProductServicesAppDir,
2799 | PackageParser.PARSE_IS_SYSTEM_DIR,
2802 | SCAN_AS_PRODUCT_SERVICES
2803 | SCAN_AS_PRIVILEGED,
2806 // Collect ordinary /product_services packages.
2807 File productServicesAppDir = new File(Environment.getProductServicesDirectory(), "app");
2809 productServicesAppDir = productServicesAppDir.getCanonicalFile();
2810 } catch (IOException e) {
2811 // failed to look up canonical path, continue with original one
2813 scanDirTracedLI(productServicesAppDir,
2815 | PackageParser.PARSE_IS_SYSTEM_DIR,
2818 | SCAN_AS_PRODUCT_SERVICES,
2821 // Prune any system packages that no longer exist.
2822 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2823 // Stub packages must either be replaced with full versions in the /data
2824 // partition or be disabled.
2825 final List<String> stubSystemApps = new ArrayList<>();
2827 // do this first before mucking with mPackages for the "expecting better" case
2828 final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2829 while (pkgIterator.hasNext()) {
2830 final PackageParser.Package pkg = pkgIterator.next();
2832 stubSystemApps.add(pkg.packageName);
2836 final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2837 while (psit.hasNext()) {
2838 PackageSetting ps = psit.next();
2841 * If this is not a system app, it can't be a
2842 * disable system app.
2844 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2849 * If the package is scanned, it's not erased.
2851 final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2852 if (scannedPkg != null) {
2854 * If the system app is both scanned and in the
2855 * disabled packages list, then it must have been
2856 * added via OTA. Remove it from the currently
2857 * scanned package so the previously user-installed
2858 * application can be scanned.
2860 if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2861 logCriticalInfo(Log.WARN,
2862 "Expecting better updated system app for " + ps.name
2863 + "; removing system app. Last known"
2864 + " codePath=" + ps.codePathString
2865 + ", versionCode=" + ps.versionCode
2866 + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
2867 removePackageLI(scannedPkg, true);
2868 mExpectingBetter.put(ps.name, ps.codePath);
2874 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2876 logCriticalInfo(Log.WARN, "System package " + ps.name
2877 + " no longer exists; it's data will be wiped");
2878 // Actual deletion of code and data will be handled by later
2879 // reconciliation step
2881 // we still have a disabled system package, but, it still might have
2882 // been removed. check the code path still exists and check there's
2883 // still a package. the latter can happen if an OTA keeps the same
2884 // code path, but, changes the package name.
2885 final PackageSetting disabledPs =
2886 mSettings.getDisabledSystemPkgLPr(ps.name);
2887 if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2888 || disabledPs.pkg == null) {
2889 possiblyDeletedUpdatedSystemApps.add(ps.name);
2891 // We're expecting that the system app should remain disabled, but add
2892 // it to expecting better to recover in case the data version cannot
2894 mExpectingBetter.put(disabledPs.name, disabledPs.codePath);
2901 deleteTempPackageFiles();
2903 final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
2905 // Remove any shared userIDs that have no associated packages
2906 mSettings.pruneSharedUsersLPw();
2907 final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2908 final int systemPackagesCount = mPackages.size();
2909 Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2910 + " ms, packageCount: " + systemPackagesCount
2911 + " , timePerPackage: "
2912 + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
2913 + " , cached: " + cachedSystemApps);
2914 if (mIsUpgrade && systemPackagesCount > 0) {
2915 MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2916 ((int) systemScanTime) / systemPackagesCount);
2919 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2920 SystemClock.uptimeMillis());
2921 scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2923 // Remove disable package settings for updated system apps that were
2924 // removed via an OTA. If the update is no longer present, remove the
2925 // app completely. Otherwise, revoke their system privileges.
2926 for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
2927 final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
2928 final PackageParser.Package pkg = mPackages.get(packageName);
2931 // remove from the disabled system list; do this first so any future
2932 // scans of this package are performed without this state
2933 mSettings.removeDisabledSystemPackageLPw(packageName);
2936 // should have found an update, but, we didn't; remove everything
2937 msg = "Updated system package " + packageName
2938 + " no longer exists; removing its data";
2939 // Actual deletion of code and data will be handled by later
2940 // reconciliation step
2942 // found an update; revoke system privileges
2943 msg = "Updated system package " + packageName
2944 + " no longer exists; rescanning package on data";
2946 // NOTE: We don't do anything special if a stub is removed from the
2947 // system image. But, if we were [like removing the uncompressed
2948 // version from the /data partition], this is where it'd be done.
2950 // remove the package from the system and re-scan it without any
2951 // special privileges
2952 removePackageLI(pkg, true);
2954 final File codePath = new File(pkg.applicationInfo.getCodePath());
2955 scanPackageTracedLI(codePath, 0, scanFlags, 0, null);
2956 } catch (PackageManagerException e) {
2957 Slog.e(TAG, "Failed to parse updated, ex-system package: "
2962 // one final check. if we still have a package setting [ie. it was
2963 // previously scanned and known to the system], but, we don't have
2964 // a package [ie. there was an error scanning it from the /data
2965 // partition], completely remove the package data.
2966 final PackageSetting ps = mSettings.mPackages.get(packageName);
2967 if (ps != null && mPackages.get(packageName) == null) {
2968 removePackageDataLIF(ps, null, null, 0, false);
2971 logCriticalInfo(Log.WARN, msg);
2975 * Make sure all system apps that we expected to appear on
2976 * the userdata partition actually showed up. If they never
2977 * appeared, crawl back and revive the system version.
2979 for (int i = 0; i < mExpectingBetter.size(); i++) {
2980 final String packageName = mExpectingBetter.keyAt(i);
2981 if (!mPackages.containsKey(packageName)) {
2982 final File scanFile = mExpectingBetter.valueAt(i);
2984 logCriticalInfo(Log.WARN, "Expected better " + packageName
2985 + " but never showed up; reverting to system");
2987 final @ParseFlags int reparseFlags;
2988 final @ScanFlags int rescanFlags;
2989 if (FileUtils.contains(privilegedAppDir, scanFile)) {
2992 PackageParser.PARSE_IS_SYSTEM_DIR;
2996 | SCAN_AS_PRIVILEGED;
2997 } else if (FileUtils.contains(systemAppDir, scanFile)) {
3000 PackageParser.PARSE_IS_SYSTEM_DIR;
3004 } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)
3005 || FileUtils.contains(privilegedOdmAppDir, scanFile)) {
3008 PackageParser.PARSE_IS_SYSTEM_DIR;
3013 | SCAN_AS_PRIVILEGED;
3014 } else if (FileUtils.contains(vendorAppDir, scanFile)
3015 || FileUtils.contains(odmAppDir, scanFile)) {
3018 PackageParser.PARSE_IS_SYSTEM_DIR;
3023 } else if (FileUtils.contains(oemAppDir, scanFile)) {
3026 PackageParser.PARSE_IS_SYSTEM_DIR;
3031 } else if (FileUtils.contains(privilegedProductAppDir, scanFile)) {
3034 PackageParser.PARSE_IS_SYSTEM_DIR;
3039 | SCAN_AS_PRIVILEGED;
3040 } else if (FileUtils.contains(productAppDir, scanFile)) {
3043 PackageParser.PARSE_IS_SYSTEM_DIR;
3048 } else if (FileUtils.contains(privilegedProductServicesAppDir, scanFile)) {
3051 PackageParser.PARSE_IS_SYSTEM_DIR;
3055 | SCAN_AS_PRODUCT_SERVICES
3056 | SCAN_AS_PRIVILEGED;
3057 } else if (FileUtils.contains(productServicesAppDir, scanFile)) {
3060 PackageParser.PARSE_IS_SYSTEM_DIR;
3064 | SCAN_AS_PRODUCT_SERVICES;
3066 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
3070 mSettings.enableSystemPackageLPw(packageName);
3073 scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
3074 } catch (PackageManagerException e) {
3075 Slog.e(TAG, "Failed to parse original system package: "
3081 // Uncompress and install any stubbed system applications.
3082 // This must be done last to ensure all stubs are replaced or disabled.
3083 installSystemStubPackages(stubSystemApps, scanFlags);
3085 final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
3088 final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
3089 final int dataPackagesCount = mPackages.size() - systemPackagesCount;
3090 Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
3091 + " ms, packageCount: " + dataPackagesCount
3092 + " , timePerPackage: "
3093 + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
3094 + " , cached: " + cachedNonSystemApps);
3095 if (mIsUpgrade && dataPackagesCount > 0) {
3096 MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
3097 ((int) dataScanTime) / dataPackagesCount);
3100 mExpectingBetter.clear();
3102 // Resolve the storage manager.
3103 mStorageManagerPackage = getStorageManagerPackageName();
3105 // Resolve protected action filters. Only the setup wizard is allowed to
3106 // have a high priority filter for these actions.
3107 mSetupWizardPackage = getSetupWizardPackageName();
3108 mComponentResolver.fixProtectedFilterPriorities();
3110 mSystemTextClassifierPackage = getSystemTextClassifierPackageName();
3112 mWellbeingPackage = getWellbeingPackageName();
3113 mDocumenterPackage = getDocumenterPackageName();
3114 mConfiguratorPackage =
3115 mContext.getString(R.string.config_deviceConfiguratorPackageName);
3116 mAppPredictionServicePackage = getAppPredictionServicePackageName();
3117 mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
3119 // Now that we know all of the shared libraries, update all clients to have
3120 // the correct library paths.
3121 updateAllSharedLibrariesLocked(null, Collections.unmodifiableMap(mPackages));
3123 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
3124 // NOTE: We ignore potential failures here during a system scan (like
3125 // the rest of the commands above) because there's precious little we
3126 // can do about it. A settings error is reported, though.
3127 final List<String> changedAbiCodePath =
3128 adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
3129 if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
3130 for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
3131 final String codePathString = changedAbiCodePath.get(i);
3133 mInstaller.rmdex(codePathString,
3134 getDexCodeInstructionSet(getPreferredInstructionSet()));
3135 } catch (InstallerException ignored) {
3139 // Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
3141 setting.fixSeInfoLocked();
3144 // Now that we know all the packages we are keeping,
3145 // read and update their last usage times.
3146 mPackageUsage.read(mPackages);
3147 mCompilerStats.read();
3149 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
3150 SystemClock.uptimeMillis());
3151 Slog.i(TAG, "Time to scan packages: "
3152 + ((SystemClock.uptimeMillis()-startTime)/1000f)
3155 // If the platform SDK has changed since the last time we booted,
3156 // we need to re-grant app permission to catch any new ones that
3157 // appear. This is really a hack, and means that apps can in some
3158 // cases get permissions that the user didn't initially explicitly
3159 // allow... it would be nice to have some better way to handle
3161 final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
3163 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
3164 + mSdkVersion + "; regranting permissions for internal storage");
3166 mPermissionManager.updateAllPermissions(
3167 StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
3168 mPermissionCallback);
3169 ver.sdkVersion = mSdkVersion;
3171 // If this is the first boot or an update from pre-M, and it is a normal
3172 // boot, then we need to initialize the default preferred apps across
3173 // all defined users.
3174 if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
3175 for (UserInfo user : sUserManager.getUsers(true)) {
3176 mSettings.applyDefaultPreferredAppsLPw(user.id);
3177 primeDomainVerificationsLPw(user.id);
3181 // Prepare storage for system user really early during boot,
3182 // since core system apps like SettingsProvider and SystemUI
3183 // can't wait for user to start
3184 final int storageFlags;
3185 if (StorageManager.isFileEncryptedNativeOrEmulated()) {
3186 storageFlags = StorageManager.FLAG_STORAGE_DE;
3188 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
3190 List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
3191 UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
3192 true /* onlyCoreApps */);
3193 mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
3194 TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
3195 Trace.TRACE_TAG_PACKAGE_MANAGER);
3196 traceLog.traceBegin("AppDataFixup");
3198 mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
3199 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
3200 } catch (InstallerException e) {
3201 Slog.w(TAG, "Trouble fixing GIDs", e);
3203 traceLog.traceEnd();
3205 traceLog.traceBegin("AppDataPrepare");
3206 if (deferPackages == null || deferPackages.isEmpty()) {
3210 for (String pkgName : deferPackages) {
3211 PackageParser.Package pkg = null;
3212 synchronized (mPackages) {
3213 PackageSetting ps = mSettings.getPackageLPr(pkgName);
3214 if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
3219 synchronized (mInstallLock) {
3220 prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
3221 true /* maybeMigrateAppData */);
3226 traceLog.traceEnd();
3227 Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
3228 }, "prepareAppData");
3230 // If this is first boot after an OTA, and a normal boot, then
3231 // we need to clear code cache directories.
3232 // Note that we do *not* clear the application profiles. These remain valid
3233 // across OTAs and are used to drive profile verification (post OTA) and
3234 // profile compilation (without waiting to collect a fresh set of profiles).
3235 if (mIsUpgrade && !onlyCore) {
3236 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
3237 for (int i = 0; i < mSettings.mPackages.size(); i++) {
3238 final PackageSetting ps = mSettings.mPackages.valueAt(i);
3239 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
3240 // No apps are running this early, so no need to freeze
3241 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
3242 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
3243 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3246 ver.fingerprint = Build.FINGERPRINT;
3249 // Grandfather existing (installed before Q) non-system apps to hide
3250 // their icons in launcher.
3251 if (!onlyCore && mIsPreQUpgrade) {
3252 Slog.i(TAG, "Whitelisting all existing apps to hide their icons");
3253 int size = mSettings.mPackages.size();
3254 for (int i = 0; i < size; i++) {
3255 final PackageSetting ps = mSettings.mPackages.valueAt(i);
3256 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
3259 ps.disableComponentLPw(PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME,
3260 UserHandle.USER_SYSTEM);
3264 // clear only after permissions and other defaults have been updated
3265 mExistingSystemPackages.clear();
3266 mPromoteSystemApps = false;
3268 // All the changes are done during package scanning.
3269 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
3271 // can downgrade to reader
3272 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
3273 mSettings.writeLPr();
3274 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3275 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3276 SystemClock.uptimeMillis());
3279 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3280 mRequiredInstallerPackage = getRequiredInstallerLPr();
3281 mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3282 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3283 if (mIntentFilterVerifierComponent != null) {
3284 mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3285 mIntentFilterVerifierComponent);
3287 mIntentFilterVerifier = null;
3289 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3290 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3291 SharedLibraryInfo.VERSION_UNDEFINED);
3292 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3293 PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3294 SharedLibraryInfo.VERSION_UNDEFINED);
3296 mRequiredVerifierPackage = null;
3297 mRequiredInstallerPackage = null;
3298 mRequiredUninstallerPackage = null;
3299 mIntentFilterVerifierComponent = null;
3300 mIntentFilterVerifier = null;
3301 mServicesSystemSharedLibraryPackageName = null;
3302 mSharedSystemSharedLibraryPackageName = null;
3304 // PermissionController hosts default permission granting and role management, so it's a
3305 // critical part of the core system.
3306 mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr();
3308 // Initialize InstantAppRegistry's Instant App list for all users.
3309 final int[] userIds = UserManagerService.getInstance().getUserIds();
3310 for (PackageParser.Package pkg : mPackages.values()) {
3311 if (pkg.isSystem()) {
3314 for (int userId : userIds) {
3315 final PackageSetting ps = (PackageSetting) pkg.mExtras;
3316 if (ps == null || !ps.getInstantApp(userId) || !ps.getInstalled(userId)) {
3319 mInstantAppRegistry.addInstantAppLPw(userId, ps.appId);
3323 mInstallerService = new PackageInstallerService(context, this, mApexManager);
3324 final Pair<ComponentName, String> instantAppResolverComponent =
3325 getInstantAppResolverLPr();
3326 if (instantAppResolverComponent != null) {
3327 if (DEBUG_INSTANT) {
3328 Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3330 mInstantAppResolverConnection = new InstantAppResolverConnection(
3331 mContext, instantAppResolverComponent.first,
3332 instantAppResolverComponent.second);
3333 mInstantAppResolverSettingsComponent =
3334 getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3336 mInstantAppResolverConnection = null;
3337 mInstantAppResolverSettingsComponent = null;
3339 updateInstantAppInstallerLocked(null);
3341 // Read and update the usage of dex files.
3342 // Do this at the end of PM init so that all the packages have their
3343 // data directory reconciled.
3344 // At this point we know the code paths of the packages, so we can validate
3345 // the disk file and build the internal cache.
3346 // The usage file is expected to be small so loading and verifying it
3347 // should take a fairly small time compare to the other activities (e.g. package
3349 final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3350 for (int userId : userIds) {
3351 userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3353 mDexManager.load(userPackages);
3355 MetricsLogger.histogram(null, "ota_package_manager_init_time",
3356 (int) (SystemClock.uptimeMillis() - startTime));
3358 } // synchronized (mPackages)
3359 } // synchronized (mInstallLock)
3361 mModuleInfoProvider = new ModuleInfoProvider(mContext, this);
3363 // Now after opening every single application zip, make sure they
3364 // are all flushed. Not really needed, but keeps things nice and
3366 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3367 Runtime.getRuntime().gc();
3368 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3370 // The initial scanning above does many calls into installd while
3371 // holding the mPackages lock, but we're mostly interested in yelling
3372 // once we have a booted system.
3373 mInstaller.setWarnIfHeld(mPackages);
3375 PackageParser.readConfigUseRoundIcon(mContext.getResources());
3377 mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);
3379 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3383 * Uncompress and install stub applications.
3384 * <p>In order to save space on the system partition, some applications are shipped in a
3385 * compressed form. In addition the compressed bits for the full application, the
3386 * system image contains a tiny stub comprised of only the Android manifest.
3387 * <p>During the first boot, attempt to uncompress and install the full application. If
3388 * the application can't be installed for any reason, disable the stub and prevent
3389 * uncompressing the full application during future boots.
3390 * <p>In order to forcefully attempt an installation of a full application, go to app
3391 * settings and enable the application.
3393 private void installSystemStubPackages(@NonNull List<String> systemStubPackageNames,
3394 @ScanFlags int scanFlags) {
3395 for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) {
3396 final String packageName = systemStubPackageNames.get(i);
3397 // skip if the system package is already disabled
3398 if (mSettings.isDisabledSystemPackageLPr(packageName)) {
3399 systemStubPackageNames.remove(i);
3402 // skip if the package isn't installed (?!); this should never happen
3403 final PackageParser.Package pkg = mPackages.get(packageName);
3405 systemStubPackageNames.remove(i);
3408 // skip if the package has been disabled by the user
3409 final PackageSetting ps = mSettings.mPackages.get(packageName);
3411 final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3412 if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3413 systemStubPackageNames.remove(i);
3418 // install the package to replace the stub on /system
3420 installStubPackageLI(pkg, 0, scanFlags);
3421 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3422 UserHandle.USER_SYSTEM, "android");
3423 systemStubPackageNames.remove(i);
3424 } catch (PackageManagerException e) {
3425 Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3428 // any failed attempt to install the package will be cleaned up later
3431 // disable any stub still left; these failed to install the full application
3432 for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) {
3433 final String pkgName = systemStubPackageNames.get(i);
3434 final PackageSetting ps = mSettings.mPackages.get(pkgName);
3435 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3436 UserHandle.USER_SYSTEM, "android");
3437 logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3442 * Extract, install and enable a stub package.
3443 * <p>If the compressed file can not be extracted / installed for any reason, the stub
3444 * APK will be installed and the package will be disabled. To recover from this situation,
3445 * the user will need to go into system settings and re-enable the package.
3447 private boolean enableCompressedPackage(PackageParser.Package stubPkg) {
3448 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
3449 | PackageParser.PARSE_ENFORCE_CODE;
3450 synchronized (mInstallLock) {
3451 final PackageParser.Package pkg;
3452 try (PackageFreezer freezer =
3453 freezePackage(stubPkg.packageName, "setEnabledSetting")) {
3454 pkg = installStubPackageLI(stubPkg, parseFlags, 0 /*scanFlags*/);
3455 synchronized (mPackages) {
3456 prepareAppDataAfterInstallLIF(pkg);
3458 updateSharedLibrariesLocked(pkg, null, mPackages);
3459 } catch (PackageManagerException e) {
3460 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
3462 mPermissionManager.updatePermissions(
3463 pkg.packageName, pkg, true, mPackages.values(),
3464 mPermissionCallback);
3465 mSettings.writeLPr();
3467 } catch (PackageManagerException e) {
3468 // Whoops! Something went very wrong; roll back to the stub and disable the package
3469 try (PackageFreezer freezer =
3470 freezePackage(stubPkg.packageName, "setEnabledSetting")) {
3471 synchronized (mPackages) {
3472 // NOTE: Ensure the system package is enabled; even for a compressed stub.
3473 // If we don't, installing the system package fails during scan
3474 enableSystemPackageLPw(stubPkg);
3476 installPackageFromSystemLIF(stubPkg.codePath,
3477 null /*allUserHandles*/, null /*origUserHandles*/,
3478 null /*origPermissionsState*/, true /*writeSettings*/);
3479 } catch (PackageManagerException pme) {
3480 // Serious WTF; we have to be able to install the stub
3481 Slog.wtf(TAG, "Failed to restore system package:" + stubPkg.packageName, pme);
3483 // Disable the package; the stub by itself is not runnable
3484 synchronized (mPackages) {
3485 final PackageSetting stubPs = mSettings.mPackages.get(stubPkg.packageName);
3486 if (stubPs != null) {
3487 stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED,
3488 UserHandle.USER_SYSTEM, "android");
3490 mSettings.writeLPr();
3495 clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
3496 | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3497 mDexManager.notifyPackageUpdated(pkg.packageName,
3498 pkg.baseCodePath, pkg.splitCodePaths);
3503 private PackageParser.Package installStubPackageLI(PackageParser.Package stubPkg,
3504 @ParseFlags int parseFlags, @ScanFlags int scanFlags)
3505 throws PackageManagerException {
3506 if (DEBUG_COMPRESSION) {
3507 Slog.i(TAG, "Uncompressing system stub; pkg: " + stubPkg.packageName);
3509 // uncompress the binary to its eventual destination on /data
3510 final File scanFile = decompressPackage(stubPkg.packageName, stubPkg.codePath);
3511 if (scanFile == null) {
3512 throw new PackageManagerException("Unable to decompress stub at " + stubPkg.codePath);
3514 synchronized (mPackages) {
3515 mSettings.disableSystemPackageLPw(stubPkg.packageName, true /*replaced*/);
3517 removePackageLI(stubPkg, true /*chatty*/);
3519 return scanPackageTracedLI(scanFile, parseFlags, scanFlags, 0, null);
3520 } catch (PackageManagerException e) {
3521 Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.packageName, e);
3522 // Remove the failed install
3523 removeCodePathLI(scanFile);
3529 * Decompresses the given package on the system image onto
3530 * the /data partition.
3531 * @return The directory the package was decompressed into. Otherwise, {@code null}.
3533 private File decompressPackage(String packageName, String codePath) {
3534 final File[] compressedFiles = getCompressedFiles(codePath);
3535 if (compressedFiles == null || compressedFiles.length == 0) {
3536 if (DEBUG_COMPRESSION) {
3537 Slog.i(TAG, "No files to decompress: " + codePath);
3541 final File dstCodePath =
3542 getNextCodePath(Environment.getDataAppDirectory(null), packageName);
3543 int ret = PackageManager.INSTALL_SUCCEEDED;
3545 Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3546 Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3547 for (File srcFile : compressedFiles) {
3548 final String srcFileName = srcFile.getName();
3549 final String dstFileName = srcFileName.substring(
3550 0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3551 final File dstFile = new File(dstCodePath, dstFileName);
3552 ret = decompressFile(srcFile, dstFile);
3553 if (ret != PackageManager.INSTALL_SUCCEEDED) {
3554 logCriticalInfo(Log.ERROR, "Failed to decompress"
3555 + "; pkg: " + packageName
3556 + ", file: " + dstFileName);
3560 } catch (ErrnoException e) {
3561 logCriticalInfo(Log.ERROR, "Failed to decompress"
3562 + "; pkg: " + packageName
3563 + ", err: " + e.errno);
3565 if (ret == PackageManager.INSTALL_SUCCEEDED) {
3566 final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3567 NativeLibraryHelper.Handle handle = null;
3569 handle = NativeLibraryHelper.Handle.create(dstCodePath);
3570 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3571 null /*abiOverride*/);
3572 } catch (IOException e) {
3573 logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3574 + "; pkg: " + packageName);
3575 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3577 IoUtils.closeQuietly(handle);
3580 if (ret != PackageManager.INSTALL_SUCCEEDED) {
3581 if (!dstCodePath.exists()) {
3584 removeCodePathLI(dstCodePath);
3591 @GuardedBy("mPackages")
3592 private void updateInstantAppInstallerLocked(String modifiedPackage) {
3593 // we're only interested in updating the installer appliction when 1) it's not
3594 // already set or 2) the modified package is the installer
3595 if (mInstantAppInstallerActivity != null
3596 && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3597 .equals(modifiedPackage)) {
3600 setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3603 private static @Nullable File preparePackageParserCache() {
3604 if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3608 // Disable package parsing on eng builds to allow for faster incremental development.
3613 if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3614 Slog.i(TAG, "Disabling package parser cache due to system property.");
3618 // The base directory for the package parser cache lives under /data/system/.
3619 final File cacheBaseDir = Environment.getPackageCacheDirectory();
3620 if (!FileUtils.createDir(cacheBaseDir)) {
3624 // There are several items that need to be combined together to safely
3625 // identify cached items. In particular, changing the value of certain
3626 // feature flags should cause us to invalidate any caches.
3627 final String cacheName = SystemProperties.digestOf(
3628 "ro.build.fingerprint",
3629 StorageManager.PROP_ISOLATED_STORAGE,
3630 StorageManager.PROP_ISOLATED_STORAGE_SNAPSHOT);
3632 // Reconcile cache directories, keeping only what we'd actually use.
3633 for (File cacheDir : FileUtils.listFilesOrEmpty(cacheBaseDir)) {
3634 if (Objects.equals(cacheName, cacheDir.getName())) {
3635 Slog.d(TAG, "Keeping known cache " + cacheDir.getName());
3637 Slog.d(TAG, "Destroying unknown cache " + cacheDir.getName());
3638 FileUtils.deleteContentsAndDir(cacheDir);
3642 // Return the versioned package cache directory.
3643 File cacheDir = FileUtils.createDir(cacheBaseDir, cacheName);
3645 if (cacheDir == null) {
3646 // Something went wrong. Attempt to delete everything and return.
3647 Slog.wtf(TAG, "Cache directory cannot be created - wiping base dir " + cacheBaseDir);
3648 FileUtils.deleteContentsAndDir(cacheBaseDir);
3652 // The following is a workaround to aid development on non-numbered userdebug
3653 // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3654 // the system partition is newer.
3656 // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3657 // that starts with "eng." to signify that this is an engineering build and not
3658 // destined for release.
3659 if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3660 Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3662 // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3663 // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3664 // in general and should not be used for production changes. In this specific case,
3665 // we know that they will work.
3666 File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3667 if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3668 FileUtils.deleteContents(cacheBaseDir);
3669 cacheDir = FileUtils.createDir(cacheBaseDir, cacheName);
3677 public boolean isFirstBoot() {
3678 // allow instant applications
3683 public boolean isOnlyCoreApps() {
3684 // allow instant applications
3689 public boolean isDeviceUpgrading() {
3690 // allow instant applications
3691 // The system property allows testing ota flow when upgraded to the same image.
3692 return mIsUpgrade || SystemProperties.getBoolean(
3693 "persist.pm.mock-upgrade", false /* default */);
3696 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3697 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3699 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3700 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3701 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3702 if (matches.size() == 1) {
3703 return matches.get(0).getComponentInfo().packageName;
3704 } else if (matches.size() == 0) {
3705 Log.e(TAG, "There should probably be a verifier, but, none were found");
3708 throw new RuntimeException("There must be exactly one verifier; found " + matches);
3711 private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3712 synchronized (mPackages) {
3713 SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(name, version);
3714 if (libraryInfo == null) {
3715 throw new IllegalStateException("Missing required shared library:" + name);
3717 String packageName = libraryInfo.getPackageName();
3718 if (packageName == null) {
3719 throw new IllegalStateException("Expected a package for shared library " + name);
3725 private @NonNull String getRequiredInstallerLPr() {
3726 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3727 intent.addCategory(Intent.CATEGORY_DEFAULT);
3728 intent.setDataAndType(Uri.parse("content://com.example/foo.apk"), PACKAGE_MIME_TYPE);
3730 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3731 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3732 UserHandle.USER_SYSTEM);
3733 if (matches.size() == 1) {
3734 ResolveInfo resolveInfo = matches.get(0);
3735 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3736 throw new RuntimeException("The installer must be a privileged app");
3738 return matches.get(0).getComponentInfo().packageName;
3740 throw new RuntimeException("There must be exactly one installer; found " + matches);
3744 private @NonNull String getRequiredUninstallerLPr() {
3745 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3746 intent.addCategory(Intent.CATEGORY_DEFAULT);
3747 intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3749 final ResolveInfo resolveInfo = resolveIntent(intent, null,
3750 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3751 UserHandle.USER_SYSTEM);
3752 if (resolveInfo == null ||
3753 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3754 throw new RuntimeException("There must be exactly one uninstaller; found "
3757 return resolveInfo.getComponentInfo().packageName;
3760 private @NonNull String getRequiredPermissionControllerLPr() {
3761 final Intent intent = new Intent(Intent.ACTION_MANAGE_PERMISSIONS);
3762 intent.addCategory(Intent.CATEGORY_DEFAULT);
3764 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
3765 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3766 UserHandle.USER_SYSTEM);
3767 if (matches.size() == 1) {
3768 ResolveInfo resolveInfo = matches.get(0);
3769 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3770 throw new RuntimeException("The permissions manager must be a privileged app");
3772 return matches.get(0).getComponentInfo().packageName;
3774 throw new RuntimeException("There must be exactly one permissions manager; found "
3779 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3780 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3782 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3783 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3784 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3785 ResolveInfo best = null;
3786 final int N = matches.size();
3787 for (int i = 0; i < N; i++) {
3788 final ResolveInfo cur = matches.get(i);
3789 final String packageName = cur.getComponentInfo().packageName;
3790 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3791 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3795 if (best == null || cur.priority > best.priority) {
3801 return best.getComponentInfo().getComponentName();
3803 Slog.w(TAG, "Intent filter verifier not found");
3808 public @Nullable ComponentName getInstantAppResolverComponent() {
3809 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3812 synchronized (mPackages) {
3813 final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3814 if (instantAppResolver == null) {
3817 return instantAppResolver.first;
3821 private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3822 final String[] packageArray =
3823 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3824 if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3825 if (DEBUG_INSTANT) {
3826 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3831 final int callingUid = Binder.getCallingUid();
3832 final int resolveFlags =
3833 MATCH_DIRECT_BOOT_AWARE
3834 | MATCH_DIRECT_BOOT_UNAWARE
3835 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3836 String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3837 final Intent resolverIntent = new Intent(actionName);
3838 List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3839 resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3840 final int N = resolvers.size();
3842 if (DEBUG_INSTANT) {
3843 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3848 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3849 for (int i = 0; i < N; i++) {
3850 final ResolveInfo info = resolvers.get(i);
3852 if (info.serviceInfo == null) {
3856 final String packageName = info.serviceInfo.packageName;
3857 if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3858 if (DEBUG_INSTANT) {
3859 Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3860 + " pkg: " + packageName + ", info:" + info);
3865 if (DEBUG_INSTANT) {
3866 Slog.v(TAG, "Ephemeral resolver found;"
3867 + " pkg: " + packageName + ", info:" + info);
3869 return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3871 if (DEBUG_INSTANT) {
3872 Slog.v(TAG, "Ephemeral resolver NOT found");
3877 @GuardedBy("mPackages")
3878 private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3879 String[] orderedActions = Build.IS_ENG
3881 Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE + "_TEST",
3882 Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE}
3884 Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE};
3886 final int resolveFlags =
3887 MATCH_DIRECT_BOOT_AWARE
3888 | MATCH_DIRECT_BOOT_UNAWARE
3889 | Intent.FLAG_IGNORE_EPHEMERAL
3890 | (!Build.IS_ENG ? MATCH_SYSTEM_ONLY : 0);
3891 final Intent intent = new Intent();
3892 intent.addCategory(Intent.CATEGORY_DEFAULT);
3893 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3894 List<ResolveInfo> matches = null;
3895 for (String action : orderedActions) {
3896 intent.setAction(action);
3897 matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3898 resolveFlags, UserHandle.USER_SYSTEM);
3899 if (matches.isEmpty()) {
3900 if (DEBUG_INSTANT) {
3901 Slog.d(TAG, "Instant App installer not found with " + action);
3907 Iterator<ResolveInfo> iter = matches.iterator();
3908 while (iter.hasNext()) {
3909 final ResolveInfo rInfo = iter.next();
3910 final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3912 final PermissionsState permissionsState = ps.getPermissionsState();
3913 if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)
3920 if (matches.size() == 0) {
3922 } else if (matches.size() == 1) {
3923 return (ActivityInfo) matches.get(0).getComponentInfo();
3925 throw new RuntimeException(
3926 "There must be at most one ephemeral installer; found " + matches);
3930 private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3931 @NonNull ComponentName resolver) {
3932 final Intent intent = new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3933 .addCategory(Intent.CATEGORY_DEFAULT)
3934 .setPackage(resolver.getPackageName());
3935 final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3936 List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3937 UserHandle.USER_SYSTEM);
3938 if (matches.isEmpty()) {
3941 return matches.get(0).getComponentInfo().getComponentName();
3944 @GuardedBy("mPackages")
3945 private void primeDomainVerificationsLPw(int userId) {
3946 if (DEBUG_DOMAIN_VERIFICATION) {
3947 Slog.d(TAG, "Priming domain verifications in user " + userId);
3950 SystemConfig systemConfig = SystemConfig.getInstance();
3951 ArraySet<String> packages = systemConfig.getLinkedApps();
3953 for (String packageName : packages) {
3954 PackageParser.Package pkg = mPackages.get(packageName);
3956 if (!pkg.isSystem()) {
3957 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3961 ArraySet<String> domains = null;
3962 for (PackageParser.Activity a : pkg.activities) {
3963 for (ActivityIntentInfo filter : a.intents) {
3964 if (hasValidDomains(filter)) {
3965 if (domains == null) {
3966 domains = new ArraySet<>();
3968 domains.addAll(filter.getHostsList());
3973 if (domains != null && domains.size() > 0) {
3974 if (DEBUG_DOMAIN_VERIFICATION) {
3975 Slog.v(TAG, " + " + packageName);
3977 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3978 // state w.r.t. the formal app-linkage "no verification attempted" state;
3979 // and then 'always' in the per-user state actually used for intent resolution.
3980 final IntentFilterVerificationInfo ivi;
3981 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3982 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3983 mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3984 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3986 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3987 + "' does not handle web links");
3990 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3994 scheduleWritePackageRestrictionsLocked(userId);
3995 scheduleWriteSettingsLocked();
3998 private boolean packageIsBrowser(String packageName, int userId) {
3999 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
4000 PackageManager.MATCH_ALL, userId);
4001 final int N = list.size();
4002 for (int i = 0; i < N; i++) {
4003 ResolveInfo info = list.get(i);
4004 if (info.priority >= 0 && packageName.equals(info.activityInfo.packageName)) {
4012 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
4013 throws RemoteException {
4015 return super.onTransact(code, data, reply, flags);
4016 } catch (RuntimeException e) {
4017 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
4018 Slog.wtf(TAG, "Package Manager Crash", e);
4025 * Returns whether or not a full application can see an instant application.
4027 * Currently, there are four cases in which this can occur:
4029 * <li>The calling application is a "special" process. Special processes
4030 * are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
4031 * <li>The calling application has the permission
4032 * {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
4033 * <li>The calling application is the default launcher on the
4034 * system partition.</li>
4035 * <li>The calling application is the default app prediction service.</li>
4038 private boolean canViewInstantApps(int callingUid, int userId) {
4039 if (callingUid < Process.FIRST_APPLICATION_UID) {
4042 if (mContext.checkCallingOrSelfPermission(
4043 android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
4046 if (mContext.checkCallingOrSelfPermission(
4047 android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
4048 final ComponentName homeComponent = getDefaultHomeActivity(userId);
4049 if (homeComponent != null
4050 && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
4053 // TODO(b/122900055) Change/Remove this and replace with new permission role.
4054 if (mAppPredictionServicePackage != null
4055 && isCallerSameApp(mAppPredictionServicePackage, callingUid)) {
4062 private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
4063 if (!sUserManager.exists(userId)) return null;
4067 final int callingUid = Binder.getCallingUid();
4068 // Filter out ephemeral app metadata:
4069 // * The system/shell/root can see metadata for any app
4070 // * An installed app can see metadata for 1) other installed apps
4071 // and 2) ephemeral apps that have explicitly interacted with it
4072 // * Ephemeral apps can only see their own data and exposed installed apps
4073 // * Holding a signature permission allows seeing instant apps
4074 if (filterAppAccessLPr(ps, callingUid, userId)) {
4078 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
4080 flags |= MATCH_ANY_USER;
4083 final PackageUserState state = ps.readUserState(userId);
4084 PackageParser.Package p = ps.pkg;
4086 final PermissionsState permissionsState = ps.getPermissionsState();
4088 // Compute GIDs only if requested
4089 final int[] gids = (flags & PackageManager.GET_GIDS) == 0
4090 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
4091 // Compute granted permissions only if package has requested permissions
4092 final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
4093 ? Collections.emptySet() : permissionsState.getPermissions(userId);
4095 PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
4096 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
4098 if (packageInfo == null) {
4102 packageInfo.packageName = packageInfo.applicationInfo.packageName =
4103 resolveExternalPackageNameLPr(p);
4106 } else if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 && state.isAvailable(flags)) {
4107 PackageInfo pi = new PackageInfo();
4108 pi.packageName = ps.name;
4109 pi.setLongVersionCode(ps.versionCode);
4110 pi.sharedUserId = (ps.sharedUser != null) ? ps.sharedUser.name : null;
4111 pi.firstInstallTime = ps.firstInstallTime;
4112 pi.lastUpdateTime = ps.lastUpdateTime;
4114 ApplicationInfo ai = new ApplicationInfo();
4115 ai.packageName = ps.name;
4116 ai.uid = UserHandle.getUid(userId, ps.appId);
4117 ai.primaryCpuAbi = ps.primaryCpuAbiString;
4118 ai.secondaryCpuAbi = ps.secondaryCpuAbiString;
4119 ai.setVersionCode(ps.versionCode);
4120 ai.flags = ps.pkgFlags;
4121 ai.privateFlags = ps.pkgPrivateFlags;
4122 pi.applicationInfo = PackageParser.generateApplicationInfo(ai, flags, state, userId);
4124 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "ps.pkg is n/a for ["
4125 + ps.name + "]. Provides a minimum info.");
4133 public void checkPackageStartable(String packageName, int userId) {
4134 final int callingUid = Binder.getCallingUid();
4135 if (getInstantAppPackageName(callingUid) != null) {
4136 throw new SecurityException("Instant applications don't have access to this method");
4138 final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
4139 synchronized (mPackages) {
4140 final PackageSetting ps = mSettings.mPackages.get(packageName);
4141 if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
4142 throw new SecurityException("Package " + packageName + " was not found!");
4145 if (!ps.getInstalled(userId)) {
4146 throw new SecurityException(
4147 "Package " + packageName + " was not installed for user " + userId + "!");
4150 if (mSafeMode && !ps.isSystem()) {
4151 throw new SecurityException("Package " + packageName + " not a system app!");
4154 if (mFrozenPackages.contains(packageName)) {
4155 throw new SecurityException("Package " + packageName + " is currently frozen!");
4158 if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
4159 throw new SecurityException("Package " + packageName + " is not encryption aware!");
4165 public boolean isPackageAvailable(String packageName, int userId) {
4166 if (!sUserManager.exists(userId)) return false;
4167 final int callingUid = Binder.getCallingUid();
4168 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4169 false /*requireFullPermission*/, false /*checkShell*/, "is package available");
4170 synchronized (mPackages) {
4171 PackageParser.Package p = mPackages.get(packageName);
4173 final PackageSetting ps = (PackageSetting) p.mExtras;
4174 if (filterAppAccessLPr(ps, callingUid, userId)) {
4178 final PackageUserState state = ps.readUserState(userId);
4179 if (state != null) {
4180 return PackageParser.isAvailable(state);
4189 public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
4190 return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
4191 flags, Binder.getCallingUid(), userId);
4195 public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
4196 int flags, int userId) {
4197 return getPackageInfoInternal(versionedPackage.getPackageName(),
4198 versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
4202 * Important: The provided filterCallingUid is used exclusively to filter out packages
4203 * that can be seen based on user state. It's typically the original caller uid prior
4204 * to clearing. Because it can only be provided by trusted code, it's value can be
4205 * trusted and will be used as-is; unlike userId which will be validated by this method.
4207 private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
4208 int flags, int filterCallingUid, int userId) {
4209 if (!sUserManager.exists(userId)) return null;
4210 flags = updateFlagsForPackage(flags, userId, packageName);
4211 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4212 false /* requireFullPermission */, false /* checkShell */, "get package info");
4215 synchronized (mPackages) {
4216 // Normalize package name to handle renamed packages and static libs
4217 packageName = resolveInternalPackageNameLPr(packageName, versionCode);
4219 final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
4220 if (matchFactoryOnly) {
4221 // Instant app filtering for APEX modules is ignored
4222 if ((flags & MATCH_APEX) != 0) {
4223 return mApexManager.getPackageInfo(packageName,
4224 ApexManager.MATCH_FACTORY_PACKAGE);
4226 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
4228 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4231 if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4234 return generatePackageInfo(ps, flags, userId);
4238 PackageParser.Package p = mPackages.get(packageName);
4239 if (matchFactoryOnly && p != null && !isSystemApp(p)) {
4242 if (DEBUG_PACKAGE_INFO)
4243 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
4245 final PackageSetting ps = (PackageSetting) p.mExtras;
4246 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4249 if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
4252 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
4254 if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
4255 final PackageSetting ps = mSettings.mPackages.get(packageName);
4256 if (ps == null) return null;
4257 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4260 if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4263 return generatePackageInfo(ps, flags, userId);
4265 if (!matchFactoryOnly && (flags & MATCH_APEX) != 0) {
4266 return mApexManager.getPackageInfo(packageName, ApexManager.MATCH_ACTIVE_PACKAGE);
4272 private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
4273 if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
4276 if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
4279 if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
4285 private boolean isComponentVisibleToInstantApp(
4286 @Nullable ComponentName component, @ComponentType int type) {
4287 if (type == TYPE_ACTIVITY) {
4288 final PackageParser.Activity activity = mComponentResolver.getActivity(component);
4289 if (activity == null) {
4292 final boolean visibleToInstantApp =
4293 (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4294 final boolean explicitlyVisibleToInstantApp =
4295 (activity.info.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
4296 return visibleToInstantApp && explicitlyVisibleToInstantApp;
4297 } else if (type == TYPE_RECEIVER) {
4298 final PackageParser.Activity activity = mComponentResolver.getReceiver(component);
4299 if (activity == null) {
4302 final boolean visibleToInstantApp =
4303 (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4304 final boolean explicitlyVisibleToInstantApp =
4305 (activity.info.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
4306 return visibleToInstantApp && !explicitlyVisibleToInstantApp;
4307 } else if (type == TYPE_SERVICE) {
4308 final PackageParser.Service service = mComponentResolver.getService(component);
4309 return service != null
4310 ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4312 } else if (type == TYPE_PROVIDER) {
4313 final PackageParser.Provider provider = mComponentResolver.getProvider(component);
4314 return provider != null
4315 ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4317 } else if (type == TYPE_UNKNOWN) {
4318 return isComponentVisibleToInstantApp(component);
4324 * Returns whether or not access to the application should be filtered.
4326 * Access may be limited based upon whether the calling or target applications
4327 * are instant applications.
4329 * @see #canViewInstantApps(int, int)
4331 @GuardedBy("mPackages")
4332 private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
4333 @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4334 // if we're in an isolated process, get the real calling UID
4335 if (Process.isIsolated(callingUid)) {
4336 callingUid = mIsolatedOwners.get(callingUid);
4338 final String instantAppPkgName = getInstantAppPackageName(callingUid);
4339 final boolean callerIsInstantApp = instantAppPkgName != null;
4341 if (callerIsInstantApp) {
4342 // pretend the application exists, but, needs to be filtered
4347 // if the target and caller are the same application, don't filter
4348 if (isCallerSameApp(ps.name, callingUid)) {
4351 if (callerIsInstantApp) {
4352 // both caller and target are both instant, but, different applications, filter
4353 if (ps.getInstantApp(userId)) {
4356 // request for a specific component; if it hasn't been explicitly exposed through
4357 // property or instrumentation target, filter
4358 if (component != null) {
4359 final PackageParser.Instrumentation instrumentation =
4360 mInstrumentation.get(component);
4361 if (instrumentation != null
4362 && isCallerSameApp(instrumentation.info.targetPackage, callingUid)) {
4365 return !isComponentVisibleToInstantApp(component, componentType);
4367 // request for application; if no components have been explicitly exposed, filter
4368 return !ps.pkg.visibleToInstantApps;
4370 if (ps.getInstantApp(userId)) {
4371 // caller can see all components of all instant applications, don't filter
4372 if (canViewInstantApps(callingUid, userId)) {
4375 // request for a specific instant application component, filter
4376 if (component != null) {
4379 // request for an instant application; if the caller hasn't been granted access, filter
4380 return !mInstantAppRegistry.isInstantAccessGranted(
4381 userId, UserHandle.getAppId(callingUid), ps.appId);
4387 * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, int, int)
4389 @GuardedBy("mPackages")
4390 private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4391 return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4394 @GuardedBy("mPackages")
4395 private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4397 // Callers can access only the libs they depend on, otherwise they need to explicitly
4398 // ask for the shared libraries given the caller is allowed to access all static libs.
4399 if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4400 // System/shell/root get to see all static libs
4401 final int appId = UserHandle.getAppId(uid);
4402 if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4403 || appId == Process.ROOT_UID) {
4406 // Installer gets to see all static libs.
4407 if (PackageManager.PERMISSION_GRANTED
4408 == checkUidPermission(Manifest.permission.INSTALL_PACKAGES, uid)) {
4413 // No package means no static lib as it is always on internal storage
4414 if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4418 final SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(ps.pkg.staticSharedLibName,
4419 ps.pkg.staticSharedLibVersion);
4420 if (libraryInfo == null) {
4424 final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4425 final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4426 if (uidPackageNames == null) {
4430 for (String uidPackageName : uidPackageNames) {
4431 if (ps.name.equals(uidPackageName)) {
4434 PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4435 if (uidPs != null) {
4436 final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4437 libraryInfo.getName());
4441 if (uidPs.pkg.usesStaticLibrariesVersions[index] == libraryInfo.getLongVersion()) {
4450 public String[] currentToCanonicalPackageNames(String[] names) {
4451 final int callingUid = Binder.getCallingUid();
4452 if (getInstantAppPackageName(callingUid) != null) {
4455 final String[] out = new String[names.length];
4457 synchronized (mPackages) {
4458 final int callingUserId = UserHandle.getUserId(callingUid);
4459 final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4460 for (int i=names.length-1; i>=0; i--) {
4461 final PackageSetting ps = mSettings.mPackages.get(names[i]);
4462 boolean translateName = false;
4463 if (ps != null && ps.realName != null) {
4464 final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4465 translateName = !targetIsInstantApp
4466 || canViewInstantApps
4467 || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4468 UserHandle.getAppId(callingUid), ps.appId);
4470 out[i] = translateName ? ps.realName : names[i];
4477 public String[] canonicalToCurrentPackageNames(String[] names) {
4478 final int callingUid = Binder.getCallingUid();
4479 if (getInstantAppPackageName(callingUid) != null) {
4482 final String[] out = new String[names.length];
4484 synchronized (mPackages) {
4485 final int callingUserId = UserHandle.getUserId(callingUid);
4486 final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4487 for (int i=names.length-1; i>=0; i--) {
4488 final String cur = mSettings.getRenamedPackageLPr(names[i]);
4489 boolean translateName = false;
4491 final PackageSetting ps = mSettings.mPackages.get(names[i]);
4492 final boolean targetIsInstantApp =
4493 ps != null && ps.getInstantApp(callingUserId);
4494 translateName = !targetIsInstantApp
4495 || canViewInstantApps
4496 || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4497 UserHandle.getAppId(callingUid), ps.appId);
4499 out[i] = translateName ? cur : names[i];
4506 public int getPackageUid(String packageName, int flags, int userId) {
4507 if (!sUserManager.exists(userId)) return -1;
4508 final int callingUid = Binder.getCallingUid();
4509 flags = updateFlagsForPackage(flags, userId, packageName);
4510 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4511 false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4514 synchronized (mPackages) {
4515 final PackageParser.Package p = mPackages.get(packageName);
4516 if (p != null && p.isMatch(flags)) {
4517 PackageSetting ps = (PackageSetting) p.mExtras;
4518 if (filterAppAccessLPr(ps, callingUid, userId)) {
4521 return UserHandle.getUid(userId, p.applicationInfo.uid);
4523 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4524 final PackageSetting ps = mSettings.mPackages.get(packageName);
4525 if (ps != null && ps.isMatch(flags)
4526 && !filterAppAccessLPr(ps, callingUid, userId)) {
4527 return UserHandle.getUid(userId, ps.appId);
4536 * Check if any package sharing/holding a uid has a low enough target SDK.
4538 * @param uid The uid of the packages
4539 * @param higherTargetSDK The target SDK that might be higher than the searched package
4541 * @return {@code true} if there is a package sharing/holding the uid with
4542 * {@code package.targetSDK < higherTargetSDK}
4544 private boolean hasTargetSdkInUidLowerThan(int uid, int higherTargetSDK) {
4545 int userId = UserHandle.getUserId(uid);
4547 synchronized (mPackages) {
4548 Object obj = mSettings.getSettingLPr(UserHandle.getAppId(uid));
4553 if (obj instanceof PackageSetting) {
4554 final PackageSetting ps = (PackageSetting) obj;
4556 if (!ps.getInstalled(userId)) {
4560 return ps.pkg.applicationInfo.targetSdkVersion < higherTargetSDK;
4561 } else if (obj instanceof SharedUserSetting) {
4562 final SharedUserSetting sus = (SharedUserSetting) obj;
4564 final int numPkgs = sus.packages.size();
4565 for (int i = 0; i < numPkgs; i++) {
4566 final PackageSetting ps = sus.packages.valueAt(i);
4568 if (!ps.getInstalled(userId)) {
4572 if (ps.pkg.applicationInfo.targetSdkVersion < higherTargetSDK) {
4585 public int[] getPackageGids(String packageName, int flags, int userId) {
4586 if (!sUserManager.exists(userId)) return null;
4587 final int callingUid = Binder.getCallingUid();
4588 flags = updateFlagsForPackage(flags, userId, packageName);
4589 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4590 false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4593 synchronized (mPackages) {
4594 final PackageParser.Package p = mPackages.get(packageName);
4595 if (p != null && p.isMatch(flags)) {
4596 PackageSetting ps = (PackageSetting) p.mExtras;
4597 if (filterAppAccessLPr(ps, callingUid, userId)) {
4600 // TODO: Shouldn't this be checking for package installed state for userId and
4602 return ps.getPermissionsState().computeGids(userId);
4604 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4605 final PackageSetting ps = mSettings.mPackages.get(packageName);
4606 if (ps != null && ps.isMatch(flags)
4607 && !filterAppAccessLPr(ps, callingUid, userId)) {
4608 return ps.getPermissionsState().computeGids(userId);
4617 public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4618 return mPermissionManager.getPermissionInfo(name, packageName, flags, getCallingUid());
4622 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
4624 final List<PermissionInfo> permissionList =
4625 mPermissionManager.getPermissionInfoByGroup(groupName, flags, getCallingUid());
4626 return (permissionList == null) ? null : new ParceledListSlice<>(permissionList);
4630 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
4631 return mPermissionManager.getPermissionGroupInfo(groupName, flags, getCallingUid());
4635 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4636 final List<PermissionGroupInfo> permissionList =
4637 mPermissionManager.getAllPermissionGroups(flags, getCallingUid());
4638 return (permissionList == null)
4639 ? ParceledListSlice.emptyList() : new ParceledListSlice<>(permissionList);
4642 @GuardedBy("mPackages")
4643 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4644 int filterCallingUid, int userId) {
4645 if (!sUserManager.exists(userId)) return null;
4646 PackageSetting ps = mSettings.mPackages.get(packageName);
4648 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4651 if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4654 if (ps.pkg == null) {
4655 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4656 if (pInfo != null) {
4657 return pInfo.applicationInfo;
4661 ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4662 ps.readUserState(userId), userId);
4664 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4672 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4673 return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4677 * Important: The provided filterCallingUid is used exclusively to filter out applications
4678 * that can be seen based on user state. It's typically the original caller uid prior
4679 * to clearing. Because it can only be provided by trusted code, it's value can be
4680 * trusted and will be used as-is; unlike userId which will be validated by this method.
4682 private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4683 int filterCallingUid, int userId) {
4684 if (!sUserManager.exists(userId)) return null;
4685 flags = updateFlagsForApplication(flags, userId, packageName);
4687 if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
4688 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4689 false /* requireFullPermission */, false /* checkShell */,
4690 "get application info");
4694 synchronized (mPackages) {
4695 // Normalize package name to handle renamed packages and static libs
4696 packageName = resolveInternalPackageNameLPr(packageName,
4697 PackageManager.VERSION_CODE_HIGHEST);
4699 PackageParser.Package p = mPackages.get(packageName);
4700 if (DEBUG_PACKAGE_INFO) Log.v(
4701 TAG, "getApplicationInfo " + packageName
4704 PackageSetting ps = mSettings.mPackages.get(packageName);
4705 if (ps == null) return null;
4706 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4709 if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4712 // Note: isEnabledLP() does not apply here - always return info
4713 ApplicationInfo ai = PackageParser.generateApplicationInfo(
4714 p, flags, ps.readUserState(userId), userId);
4716 ai.packageName = resolveExternalPackageNameLPr(p);
4720 if ("android".equals(packageName)||"system".equals(packageName)) {
4721 return mAndroidApplication;
4723 if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4724 // Already generates the external package name
4725 return generateApplicationInfoFromSettingsLPw(packageName,
4726 flags, filterCallingUid, userId);
4732 @GuardedBy("mPackages")
4733 private String normalizePackageNameLPr(String packageName) {
4734 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4735 return normalizedPackageName != null ? normalizedPackageName : packageName;
4739 public void deletePreloadsFileCache() {
4740 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CLEAR_APP_CACHE,
4741 "deletePreloadsFileCache");
4742 File dir = Environment.getDataPreloadsFileCacheDirectory();
4743 Slog.i(TAG, "Deleting preloaded file cache " + dir);
4744 FileUtils.deleteContents(dir);
4748 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4749 final int storageFlags, final IPackageDataObserver observer) {
4750 mContext.enforceCallingOrSelfPermission(
4751 android.Manifest.permission.CLEAR_APP_CACHE, null);
4752 mHandler.post(() -> {
4753 boolean success = false;
4755 freeStorage(volumeUuid, freeStorageSize, storageFlags);
4757 } catch (IOException e) {
4760 if (observer != null) {
4762 observer.onRemoveCompleted(null, success);
4763 } catch (RemoteException e) {
4771 public void freeStorage(final String volumeUuid, final long freeStorageSize,
4772 final int storageFlags, final IntentSender pi) {
4773 mContext.enforceCallingOrSelfPermission(
4774 android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4775 mHandler.post(() -> {
4776 boolean success = false;
4778 freeStorage(volumeUuid, freeStorageSize, storageFlags);
4780 } catch (IOException e) {
4785 pi.sendIntent(null, success ? 1 : 0, null, null, null);
4786 } catch (SendIntentException e) {
4794 * Blocking call to clear various types of cached data across the system
4795 * until the requested bytes are available.
4797 public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4798 final StorageManager storage = mContext.getSystemService(StorageManager.class);
4799 final File file = storage.findPathForUuid(volumeUuid);
4800 if (file.getUsableSpace() >= bytes) return;
4802 if (ENABLE_FREE_CACHE_V2) {
4803 final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4805 final boolean aggressive = (storageFlags
4806 & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4807 final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4809 // 1. Pre-flight to determine if we have any chance to succeed
4810 // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4811 if (internalVolume && (aggressive || SystemProperties
4812 .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4813 deletePreloadsFileCache();
4814 if (file.getUsableSpace() >= bytes) return;
4817 // 3. Consider parsed APK data (aggressive only)
4818 if (internalVolume && aggressive) {
4819 FileUtils.deleteContents(mCacheDir);
4820 if (file.getUsableSpace() >= bytes) return;
4823 // 4. Consider cached app data (above quotas)
4825 mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4826 Installer.FLAG_FREE_CACHE_V2);
4827 } catch (InstallerException ignored) {
4829 if (file.getUsableSpace() >= bytes) return;
4831 // 5. Consider shared libraries with refcount=0 and age>min cache period
4832 if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4833 android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4834 Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4835 DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4839 // 6. Consider dexopt output (aggressive only)
4842 // 7. Consider installed instant apps unused longer than min cache period
4843 if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4844 android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4845 Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4846 InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4850 // 8. Consider cached app data (below quotas)
4852 mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4853 Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4854 } catch (InstallerException ignored) {
4856 if (file.getUsableSpace() >= bytes) return;
4858 // 9. Consider DropBox entries
4861 // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4862 if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4863 android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4864 Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4865 InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4870 mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4871 } catch (InstallerException ignored) {
4873 if (file.getUsableSpace() >= bytes) return;
4876 throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4879 private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4880 throws IOException {
4881 final StorageManager storage = mContext.getSystemService(StorageManager.class);
4882 final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4884 List<VersionedPackage> packagesToDelete = null;
4885 final long now = System.currentTimeMillis();
4887 synchronized (mPackages) {
4888 final int[] allUsers = sUserManager.getUserIds();
4889 final int libCount = mSharedLibraries.size();
4890 for (int i = 0; i < libCount; i++) {
4891 final LongSparseArray<SharedLibraryInfo> versionedLib
4892 = mSharedLibraries.valueAt(i);
4893 if (versionedLib == null) {
4896 final int versionCount = versionedLib.size();
4897 for (int j = 0; j < versionCount; j++) {
4898 SharedLibraryInfo libInfo = versionedLib.valueAt(j);
4899 // Skip packages that are not static shared libs.
4900 if (!libInfo.isStatic()) {
4903 // Important: We skip static shared libs used for some user since
4904 // in such a case we need to keep the APK on the device. The check for
4905 // a lib being used for any user is performed by the uninstall call.
4906 final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4907 // Resolve the package name - we use synthetic package names internally
4908 final String internalPackageName = resolveInternalPackageNameLPr(
4909 declaringPackage.getPackageName(),
4910 declaringPackage.getLongVersionCode());
4911 final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4912 // Skip unused static shared libs cached less than the min period
4913 // to prevent pruning a lib needed by a subsequently installed package.
4914 if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4918 if (ps.pkg.isSystem()) {
4922 if (packagesToDelete == null) {
4923 packagesToDelete = new ArrayList<>();
4925 packagesToDelete.add(new VersionedPackage(internalPackageName,
4926 declaringPackage.getLongVersionCode()));
4931 if (packagesToDelete != null) {
4932 final int packageCount = packagesToDelete.size();
4933 for (int i = 0; i < packageCount; i++) {
4934 final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4935 // Delete the package synchronously (will fail of the lib used for any user).
4936 if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getLongVersionCode(),
4937 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4938 == PackageManager.DELETE_SUCCEEDED) {
4939 if (volume.getUsableSpace() >= neededSpace) {
4950 * Update given flags based on encryption status of current user.
4952 private int updateFlags(int flags, int userId) {
4953 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4954 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4955 // Caller expressed an explicit opinion about what encryption
4956 // aware/unaware components they want to see, so fall through and
4957 // give them what they want
4959 // Caller expressed no opinion, so match based on user state
4960 if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4961 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4963 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4969 private UserManagerInternal getUserManagerInternal() {
4970 if (mUserManagerInternal == null) {
4971 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4973 return mUserManagerInternal;
4976 private ActivityManagerInternal getActivityManagerInternal() {
4977 if (mActivityManagerInternal == null) {
4978 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
4980 return mActivityManagerInternal;
4983 private ActivityTaskManagerInternal getActivityTaskManagerInternal() {
4984 if (mActivityTaskManagerInternal == null) {
4985 mActivityTaskManagerInternal =
4986 LocalServices.getService(ActivityTaskManagerInternal.class);
4988 return mActivityTaskManagerInternal;
4991 private DeviceIdleController.LocalService getDeviceIdleController() {
4992 if (mDeviceIdleController == null) {
4993 mDeviceIdleController =
4994 LocalServices.getService(DeviceIdleController.LocalService.class);
4996 return mDeviceIdleController;
4999 private StorageManagerInternal getStorageManagerInternal() {
5000 if (mStorageManagerInternal == null) {
5001 mStorageManagerInternal = LocalServices.getService(StorageManagerInternal.class);
5003 return mStorageManagerInternal;
5007 * Update given flags when being used to request {@link PackageInfo}.
5009 private int updateFlagsForPackage(int flags, int userId, Object cookie) {
5010 final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
5011 if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
5012 // require the permission to be held; the calling uid and given user id referring
5013 // to the same user is not sufficient
5014 mPermissionManager.enforceCrossUserPermission(
5015 Binder.getCallingUid(), userId, false, false,
5016 !isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId),
5017 "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
5018 + Debug.getCallers(5));
5019 } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
5020 && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
5021 // If the caller wants all packages and has a restricted profile associated with it,
5022 // then match all users. This is to make sure that launchers that need to access work
5023 // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
5024 // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
5025 flags |= PackageManager.MATCH_ANY_USER;
5027 return updateFlags(flags, userId);
5031 * Update given flags when being used to request {@link ApplicationInfo}.
5033 private int updateFlagsForApplication(int flags, int userId, Object cookie) {
5034 return updateFlagsForPackage(flags, userId, cookie);
5038 * Update given flags when being used to request {@link ComponentInfo}.
5040 private int updateFlagsForComponent(int flags, int userId, Object cookie) {
5041 return updateFlags(flags, userId);
5045 * Update given intent when being used to request {@link ResolveInfo}.
5047 private Intent updateIntentForResolve(Intent intent) {
5048 if (intent.getSelector() != null) {
5049 intent = intent.getSelector();
5051 if (DEBUG_PREFERRED) {
5052 intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
5058 * Update given flags when being used to request {@link ResolveInfo}.
5059 * <p>Instant apps are resolved specially, depending upon context. Minimally,
5060 * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
5061 * flag set. However, this flag is only honoured in three circumstances:
5063 * <li>when called from a system process</li>
5064 * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
5065 * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
5066 * action and a {@code android.intent.category.BROWSABLE} category</li>
5069 int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
5070 return updateFlagsForResolve(flags, userId, intent, callingUid,
5071 false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
5073 int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
5074 boolean wantInstantApps) {
5075 return updateFlagsForResolve(flags, userId, intent, callingUid,
5076 wantInstantApps, false /*onlyExposedExplicitly*/);
5078 int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
5079 boolean wantInstantApps, boolean onlyExposedExplicitly) {
5080 // Safe mode means we shouldn't match any third-party components
5082 flags |= PackageManager.MATCH_SYSTEM_ONLY;
5084 if (getInstantAppPackageName(callingUid) != null) {
5085 // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
5086 if (onlyExposedExplicitly) {
5087 flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
5089 flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
5090 flags |= PackageManager.MATCH_INSTANT;
5092 final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
5093 final boolean allowMatchInstant = wantInstantApps
5094 || (wantMatchInstant && canViewInstantApps(callingUid, userId));
5095 flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
5096 | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
5097 if (!allowMatchInstant) {
5098 flags &= ~PackageManager.MATCH_INSTANT;
5101 return updateFlagsForComponent(flags, userId, intent /*cookie*/);
5105 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
5106 return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
5110 * Important: The provided filterCallingUid is used exclusively to filter out activities
5111 * that can be seen based on user state. It's typically the original caller uid prior
5112 * to clearing. Because it can only be provided by trusted code, it's value can be
5113 * trusted and will be used as-is; unlike userId which will be validated by this method.
5115 private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
5116 int filterCallingUid, int userId) {
5117 if (!sUserManager.exists(userId)) return null;
5118 flags = updateFlagsForComponent(flags, userId, component);
5120 if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
5121 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
5122 false /* requireFullPermission */, false /* checkShell */, "get activity info");
5125 synchronized (mPackages) {
5126 PackageParser.Activity a = mComponentResolver.getActivity(component);
5128 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
5129 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
5130 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5131 if (ps == null) return null;
5132 if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
5135 return PackageParser.generateActivityInfo(
5136 a, flags, ps.readUserState(userId), userId);
5138 if (mResolveComponentName.equals(component)) {
5139 return PackageParser.generateActivityInfo(
5140 mResolveActivity, flags, new PackageUserState(), userId);
5146 private boolean isRecentsAccessingChildProfiles(int callingUid, int targetUserId) {
5147 if (!getActivityTaskManagerInternal().isCallerRecents(callingUid)) {
5150 final long token = Binder.clearCallingIdentity();
5152 final int callingUserId = UserHandle.getUserId(callingUid);
5153 if (ActivityManager.getCurrentUser() != callingUserId) {
5156 return sUserManager.isSameProfileGroup(callingUserId, targetUserId);
5158 Binder.restoreCallingIdentity(token);
5163 public boolean activitySupportsIntent(ComponentName component, Intent intent,
5164 String resolvedType) {
5165 synchronized (mPackages) {
5166 if (component.equals(mResolveComponentName)) {
5167 // The resolver supports EVERYTHING!
5170 final int callingUid = Binder.getCallingUid();
5171 final int callingUserId = UserHandle.getUserId(callingUid);
5172 PackageParser.Activity a = mComponentResolver.getActivity(component);
5176 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5180 if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
5183 for (int i=0; i<a.intents.size(); i++) {
5184 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
5185 intent.getData(), intent.getCategories(), TAG) >= 0) {
5194 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
5195 if (!sUserManager.exists(userId)) return null;
5196 final int callingUid = Binder.getCallingUid();
5197 flags = updateFlagsForComponent(flags, userId, component);
5198 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5199 false /* requireFullPermission */, false /* checkShell */, "get receiver info");
5200 synchronized (mPackages) {
5201 PackageParser.Activity a = mComponentResolver.getReceiver(component);
5202 if (DEBUG_PACKAGE_INFO) Log.v(
5203 TAG, "getReceiverInfo " + component + ": " + a);
5204 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
5205 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5206 if (ps == null) return null;
5207 if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
5210 return PackageParser.generateActivityInfo(
5211 a, flags, ps.readUserState(userId), userId);
5218 public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
5219 int flags, int userId) {
5220 if (!sUserManager.exists(userId)) return null;
5221 Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
5222 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5226 flags = updateFlagsForPackage(flags, userId, null);
5228 final boolean canSeeStaticLibraries =
5229 mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
5230 == PERMISSION_GRANTED
5231 || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
5232 == PERMISSION_GRANTED
5233 || canRequestPackageInstallsInternal(packageName,
5234 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
5235 false /* throwIfPermNotDeclared*/)
5236 || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
5237 == PERMISSION_GRANTED
5238 || mContext.checkCallingOrSelfPermission(
5239 Manifest.permission.ACCESS_SHARED_LIBRARIES) == PERMISSION_GRANTED;
5241 synchronized (mPackages) {
5242 List<SharedLibraryInfo> result = null;
5244 final int libCount = mSharedLibraries.size();
5245 for (int i = 0; i < libCount; i++) {
5246 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.valueAt(i);
5247 if (versionedLib == null) {
5251 final int versionCount = versionedLib.size();
5252 for (int j = 0; j < versionCount; j++) {
5253 SharedLibraryInfo libInfo = versionedLib.valueAt(j);
5254 if (!canSeeStaticLibraries && libInfo.isStatic()) {
5257 final long identity = Binder.clearCallingIdentity();
5259 PackageInfo packageInfo = getPackageInfoVersioned(
5260 libInfo.getDeclaringPackage(), flags
5261 | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
5262 if (packageInfo == null) {
5266 Binder.restoreCallingIdentity(identity);
5269 SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getPath(),
5270 libInfo.getPackageName(), libInfo.getAllCodePaths(),
5271 libInfo.getName(), libInfo.getLongVersion(),
5272 libInfo.getType(), libInfo.getDeclaringPackage(),
5273 getPackagesUsingSharedLibraryLPr(libInfo, flags, userId),
5274 (libInfo.getDependencies() == null
5276 : new ArrayList<>(libInfo.getDependencies())));
5278 if (result == null) {
5279 result = new ArrayList<>();
5281 result.add(resLibInfo);
5285 return result != null ? new ParceledListSlice<>(result) : null;
5291 public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
5292 @NonNull String packageName, int flags, @NonNull int userId) {
5293 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_SHARED_LIBRARIES,
5294 "getDeclaredSharedLibraries");
5295 int callingUid = Binder.getCallingUid();
5296 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5297 true /* requireFullPermission */, false /* checkShell */,
5298 "getDeclaredSharedLibraries");
5300 Preconditions.checkNotNull(packageName, "packageName cannot be null");
5301 Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
5302 if (!sUserManager.exists(userId)) {
5306 if (getInstantAppPackageName(callingUid) != null) {
5310 synchronized (mPackages) {
5311 List<SharedLibraryInfo> result = null;
5313 int libraryCount = mSharedLibraries.size();
5314 for (int i = 0; i < libraryCount; i++) {
5315 LongSparseArray<SharedLibraryInfo> versionedLibrary = mSharedLibraries.valueAt(i);
5316 if (versionedLibrary == null) {
5320 int versionCount = versionedLibrary.size();
5321 for (int j = 0; j < versionCount; j++) {
5322 SharedLibraryInfo libraryInfo = versionedLibrary.valueAt(j);
5324 VersionedPackage declaringPackage = libraryInfo.getDeclaringPackage();
5325 if (!Objects.equals(declaringPackage.getPackageName(), packageName)) {
5329 long identity = Binder.clearCallingIdentity();
5331 PackageInfo packageInfo = getPackageInfoVersioned(declaringPackage, flags
5332 | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
5333 if (packageInfo == null) {
5337 Binder.restoreCallingIdentity(identity);
5340 SharedLibraryInfo resultLibraryInfo = new SharedLibraryInfo(
5341 libraryInfo.getPath(), libraryInfo.getPackageName(),
5342 libraryInfo.getAllCodePaths(), libraryInfo.getName(),
5343 libraryInfo.getLongVersion(), libraryInfo.getType(),
5344 libraryInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(
5345 libraryInfo, flags, userId), libraryInfo.getDependencies() == null
5346 ? null : new ArrayList<>(libraryInfo.getDependencies()));
5348 if (result == null) {
5349 result = new ArrayList<>();
5351 result.add(resultLibraryInfo);
5355 return result != null ? new ParceledListSlice<>(result) : null;
5359 @GuardedBy("mPackages")
5360 private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
5361 SharedLibraryInfo libInfo, int flags, int userId) {
5362 List<VersionedPackage> versionedPackages = null;
5363 final int packageCount = mSettings.mPackages.size();
5364 for (int i = 0; i < packageCount; i++) {
5365 PackageSetting ps = mSettings.mPackages.valueAt(i);
5371 if (!ps.readUserState(userId).isAvailable(flags)) {
5375 final String libName = libInfo.getName();
5376 if (libInfo.isStatic()) {
5377 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
5381 if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getLongVersion()) {
5384 if (versionedPackages == null) {
5385 versionedPackages = new ArrayList<>();
5387 // If the dependent is a static shared lib, use the public package name
5388 String dependentPackageName = ps.name;
5389 if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
5390 dependentPackageName = ps.pkg.manifestPackageName;
5392 versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
5393 } else if (ps.pkg != null) {
5394 if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
5395 || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
5396 if (versionedPackages == null) {
5397 versionedPackages = new ArrayList<>();
5399 versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
5404 return versionedPackages;
5408 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5409 if (!sUserManager.exists(userId)) return null;
5410 final int callingUid = Binder.getCallingUid();
5411 flags = updateFlagsForComponent(flags, userId, component);
5412 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5413 false /* requireFullPermission */, false /* checkShell */, "get service info");
5414 synchronized (mPackages) {
5415 PackageParser.Service s = mComponentResolver.getService(component);
5416 if (DEBUG_PACKAGE_INFO) Log.v(
5417 TAG, "getServiceInfo " + component + ": " + s);
5418 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
5419 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5420 if (ps == null) return null;
5421 if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
5424 return PackageParser.generateServiceInfo(
5425 s, flags, ps.readUserState(userId), userId);
5432 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
5433 if (!sUserManager.exists(userId)) return null;
5434 final int callingUid = Binder.getCallingUid();
5435 flags = updateFlagsForComponent(flags, userId, component);
5436 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5437 false /* requireFullPermission */, false /* checkShell */, "get provider info");
5438 synchronized (mPackages) {
5439 PackageParser.Provider p = mComponentResolver.getProvider(component);
5440 if (DEBUG_PACKAGE_INFO) Log.v(
5441 TAG, "getProviderInfo " + component + ": " + p);
5442 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
5443 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5444 if (ps == null) return null;
5445 if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
5448 return PackageParser.generateProviderInfo(
5449 p, flags, ps.readUserState(userId), userId);
5456 public ModuleInfo getModuleInfo(String packageName, @ModuleInfoFlags int flags) {
5457 return mModuleInfoProvider.getModuleInfo(packageName, flags);
5461 public List<ModuleInfo> getInstalledModules(int flags) {
5462 return mModuleInfoProvider.getInstalledModules(flags);
5466 public String[] getSystemSharedLibraryNames() {
5467 // allow instant applications
5468 synchronized (mPackages) {
5469 Set<String> libs = null;
5470 final int libCount = mSharedLibraries.size();
5471 for (int i = 0; i < libCount; i++) {
5472 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.valueAt(i);
5473 if (versionedLib == null) {
5476 final int versionCount = versionedLib.size();
5477 for (int j = 0; j < versionCount; j++) {
5478 SharedLibraryInfo libraryInfo = versionedLib.valueAt(j);
5479 if (!libraryInfo.isStatic()) {
5481 libs = new ArraySet<>();
5483 libs.add(libraryInfo.getName());
5486 PackageSetting ps = mSettings.getPackageLPr(libraryInfo.getPackageName());
5487 if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
5488 UserHandle.getUserId(Binder.getCallingUid()),
5489 PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
5491 libs = new ArraySet<>();
5493 libs.add(libraryInfo.getName());
5500 String[] libsArray = new String[libs.size()];
5501 libs.toArray(libsArray);
5510 public @NonNull String getServicesSystemSharedLibraryPackageName() {
5511 // allow instant applications
5512 synchronized (mPackages) {
5513 return mServicesSystemSharedLibraryPackageName;
5518 public @NonNull String getSharedSystemSharedLibraryPackageName() {
5519 // allow instant applications
5520 synchronized (mPackages) {
5521 return mSharedSystemSharedLibraryPackageName;
5525 @GuardedBy("mPackages")
5526 private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5527 for (int i = userList.length - 1; i >= 0; --i) {
5528 final int userId = userList[i];
5529 // don't add instant app to the list of updates
5530 if (pkgSetting.getInstantApp(userId)) {
5533 SparseArray<String> changedPackages = mChangedPackages.get(userId);
5534 if (changedPackages == null) {
5535 changedPackages = new SparseArray<>();
5536 mChangedPackages.put(userId, changedPackages);
5538 Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5539 if (sequenceNumbers == null) {
5540 sequenceNumbers = new HashMap<>();
5541 mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5543 final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5544 if (sequenceNumber != null) {
5545 changedPackages.remove(sequenceNumber);
5547 changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5548 sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5550 mChangedPackagesSequenceNumber++;
5554 public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5555 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5558 synchronized (mPackages) {
5559 if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5562 final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5563 if (changedPackages == null) {
5566 final List<String> packageNames =
5567 new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5568 for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5569 final String packageName = changedPackages.get(i);
5570 if (packageName != null) {
5571 packageNames.add(packageName);
5574 return packageNames.isEmpty()
5575 ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5580 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5581 // allow instant applications
5582 ArrayList<FeatureInfo> res;
5583 synchronized (mAvailableFeatures) {
5584 res = new ArrayList<>(mAvailableFeatures.size() + 1);
5585 res.addAll(mAvailableFeatures.values());
5587 final FeatureInfo fi = new FeatureInfo();
5588 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5589 FeatureInfo.GL_ES_VERSION_UNDEFINED);
5592 return new ParceledListSlice<>(res);
5596 public boolean hasSystemFeature(String name, int version) {
5597 // allow instant applications
5598 synchronized (mAvailableFeatures) {
5599 final FeatureInfo feat = mAvailableFeatures.get(name);
5603 return feat.version >= version;
5609 public int checkPermission(String permName, String pkgName, int userId) {
5610 final CheckPermissionDelegate checkPermissionDelegate;
5611 synchronized (mPackages) {
5612 if (mCheckPermissionDelegate == null) {
5613 return checkPermissionImpl(permName, pkgName, userId);
5615 checkPermissionDelegate = mCheckPermissionDelegate;
5617 return checkPermissionDelegate.checkPermission(permName, pkgName, userId,
5618 PackageManagerService.this::checkPermissionImpl);
5621 private int checkPermissionImpl(String permName, String pkgName, int userId) {
5622 return mPermissionManager.checkPermission(permName, pkgName, getCallingUid(), userId);
5626 public int checkUidPermission(String permName, int uid) {
5627 final CheckPermissionDelegate checkPermissionDelegate;
5628 synchronized (mPackages) {
5629 if (mCheckPermissionDelegate == null) {
5630 return checkUidPermissionImpl(permName, uid);
5632 checkPermissionDelegate = mCheckPermissionDelegate;
5634 return checkPermissionDelegate.checkUidPermission(permName, uid,
5635 PackageManagerService.this::checkUidPermissionImpl);
5638 private int checkUidPermissionImpl(String permName, int uid) {
5639 synchronized (mPackages) {
5640 final String[] packageNames = getPackagesForUid(uid);
5641 PackageParser.Package pkg = null;
5642 final int N = packageNames == null ? 0 : packageNames.length;
5643 for (int i = 0; pkg == null && i < N; i++) {
5644 pkg = mPackages.get(packageNames[i]);
5646 return mPermissionManager.checkUidPermission(permName, pkg, uid, getCallingUid());
5651 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5652 if (UserHandle.getCallingUserId() != userId) {
5653 mContext.enforceCallingPermission(
5654 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5655 "isPermissionRevokedByPolicy for user " + userId);
5658 if (checkPermission(permission, packageName, userId)
5659 == PackageManager.PERMISSION_GRANTED) {
5663 final int callingUid = Binder.getCallingUid();
5664 if (getInstantAppPackageName(callingUid) != null) {
5665 if (!isCallerSameApp(packageName, callingUid)) {
5669 if (isInstantApp(packageName, userId)) {
5674 final long identity = Binder.clearCallingIdentity();
5676 final int flags = getPermissionFlags(permission, packageName, userId);
5677 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5679 Binder.restoreCallingIdentity(identity);
5684 public String getPermissionControllerPackageName() {
5685 synchronized (mPackages) {
5686 return mRequiredPermissionControllerPackage;
5690 String getPackageInstallerPackageName() {
5691 synchronized (mPackages) {
5692 return mRequiredInstallerPackage;
5696 private boolean addDynamicPermission(PermissionInfo info, final boolean async) {
5697 return mPermissionManager.addDynamicPermission(
5698 info, async, getCallingUid(), new PermissionCallback() {
5700 public void onPermissionChanged() {
5702 mSettings.writeLPr();
5704 scheduleWriteSettingsLocked();
5711 public boolean addPermission(PermissionInfo info) {
5712 synchronized (mPackages) {
5713 return addDynamicPermission(info, false);
5718 public boolean addPermissionAsync(PermissionInfo info) {
5719 synchronized (mPackages) {
5720 return addDynamicPermission(info, true);
5725 public void removePermission(String permName) {
5726 mPermissionManager.removeDynamicPermission(permName, getCallingUid(), mPermissionCallback);
5730 public void grantRuntimePermission(String packageName, String permName, final int userId) {
5731 boolean overridePolicy = (checkUidPermission(
5732 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, Binder.getCallingUid())
5733 == PackageManager.PERMISSION_GRANTED);
5735 mPermissionManager.grantRuntimePermission(permName, packageName, overridePolicy,
5736 getCallingUid(), userId, mPermissionCallback);
5740 public void revokeRuntimePermission(String packageName, String permName, int userId) {
5741 boolean overridePolicy = (checkUidPermission(
5742 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, Binder.getCallingUid())
5743 == PackageManager.PERMISSION_GRANTED);
5745 mPermissionManager.revokeRuntimePermission(permName, packageName, overridePolicy,
5746 userId, mPermissionCallback);
5750 public void resetRuntimePermissions() {
5751 mContext.enforceCallingOrSelfPermission(
5752 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5753 "revokeRuntimePermission");
5755 int callingUid = Binder.getCallingUid();
5756 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5757 mContext.enforceCallingOrSelfPermission(
5758 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5759 "resetRuntimePermissions");
5762 synchronized (mPackages) {
5763 mPermissionManager.updateAllPermissions(
5764 StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
5765 mPermissionCallback);
5766 for (int userId : UserManagerService.getInstance().getUserIds()) {
5767 final int packageCount = mPackages.size();
5768 for (int i = 0; i < packageCount; i++) {
5769 PackageParser.Package pkg = mPackages.valueAt(i);
5770 if (!(pkg.mExtras instanceof PackageSetting)) {
5773 PackageSetting ps = (PackageSetting) pkg.mExtras;
5774 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5781 public int getPermissionFlags(String permName, String packageName, int userId) {
5782 return mPermissionManager.getPermissionFlags(
5783 permName, packageName, getCallingUid(), userId);
5787 public void updatePermissionFlags(String permName, String packageName, int flagMask,
5788 int flagValues, boolean checkAdjustPolicyFlagPermission, int userId) {
5789 int callingUid = getCallingUid();
5790 boolean overridePolicy = false;
5792 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
5793 long callingIdentity = Binder.clearCallingIdentity();
5795 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0) {
5796 if (checkAdjustPolicyFlagPermission) {
5797 mContext.enforceCallingOrSelfPermission(
5798 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
5799 "Need " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY
5800 + " to change policy flags");
5801 } else if (!hasTargetSdkInUidLowerThan(callingUid, Build.VERSION_CODES.Q)) {
5802 throw new IllegalArgumentException(
5803 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " needs "
5804 + " to be checked for packages targeting "
5805 + Build.VERSION_CODES.Q + " or later when changing policy "
5809 overridePolicy = true;
5812 Binder.restoreCallingIdentity(callingIdentity);
5816 mPermissionManager.updatePermissionFlags(
5817 permName, packageName, flagMask, flagValues, callingUid, userId,
5818 overridePolicy, mPermissionCallback);
5822 * Update the permission flags for all packages and runtime permissions of a user in order
5823 * to allow device or profile owner to remove POLICY_FIXED.
5826 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5827 synchronized (mPackages) {
5828 final boolean changed = mPermissionManager.updatePermissionFlagsForAllApps(
5829 flagMask, flagValues, getCallingUid(), userId, mPackages.values(),
5830 mPermissionCallback);
5832 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5838 public @Nullable List<String> getWhitelistedRestrictedPermissions(@NonNull String packageName,
5839 @PermissionWhitelistFlags int whitelistFlags, @UserIdInt int userId) {
5840 Preconditions.checkNotNull(packageName);
5841 Preconditions.checkFlagsArgument(whitelistFlags,
5842 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
5843 | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
5844 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
5845 Preconditions.checkArgumentNonNegative(userId, null);
5847 if (UserHandle.getCallingUserId() != userId) {
5848 mContext.enforceCallingOrSelfPermission(
5849 android.Manifest.permission.INTERACT_ACROSS_USERS,
5850 "getWhitelistedRestrictedPermissions for user " + userId);
5853 final PackageParser.Package pkg;
5855 synchronized (mPackages) {
5856 final PackageSetting packageSetting = mSettings.mPackages.get(packageName);
5857 if (packageSetting == null) {
5858 Slog.w(TAG, "Unknown package: " + packageName);
5862 pkg = packageSetting.pkg;
5864 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
5865 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
5866 == PackageManager.PERMISSION_GRANTED;
5867 final PackageSetting installerPackageSetting = mSettings.mPackages.get(
5868 packageSetting.installerPackageName);
5869 final boolean isCallerInstallerOnRecord = installerPackageSetting != null
5870 && UserHandle.isSameApp(installerPackageSetting.appId, Binder.getCallingUid());
5872 if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
5873 && !isCallerPrivileged) {
5874 throw new SecurityException("Querying system whitelist requires "
5875 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
5878 if ((whitelistFlags & (PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
5879 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER)) != 0) {
5880 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
5881 throw new SecurityException("Querying upgrade or installer whitelist"
5882 + " requires being installer on record or "
5883 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
5887 if (filterAppAccessLPr(packageSetting, Binder.getCallingUid(),
5888 UserHandle.getCallingUserId())) {
5893 final long identity = Binder.clearCallingIdentity();
5895 return mPermissionManager.getWhitelistedRestrictedPermissions(
5896 pkg, whitelistFlags, userId);
5898 Binder.restoreCallingIdentity(identity);
5903 public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
5904 @NonNull String permission, @PermissionWhitelistFlags int whitelistFlags,
5905 @UserIdInt int userId) {
5906 // Other argument checks are done in get/setWhitelistedRestrictedPermissions
5907 Preconditions.checkNotNull(permission);
5909 if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permission)) {
5913 List<String> permissions = getWhitelistedRestrictedPermissions(packageName,
5914 whitelistFlags, userId);
5915 if (permissions == null) {
5916 permissions = new ArrayList<>(1);
5918 if (permissions.indexOf(permission) < 0) {
5919 permissions.add(permission);
5920 return setWhitelistedRestrictedPermissions(packageName, permissions,
5921 whitelistFlags, userId);
5926 private boolean checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(
5927 @NonNull String permission) {
5928 synchronized (mPackages) {
5929 final BasePermission bp = mPermissionManager.getPermissionTEMP(permission);
5931 Slog.w(TAG, "No such permissions: " + permission);
5934 if (bp.isHardOrSoftRestricted() && bp.isImmutablyRestricted()
5935 && mContext.checkCallingOrSelfPermission(
5936 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
5937 != PackageManager.PERMISSION_GRANTED) {
5938 throw new SecurityException("Cannot modify whitelisting of an immutably "
5939 + "restricted permission: " + permission);
5946 public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
5947 @NonNull String permission, @PermissionWhitelistFlags int whitelistFlags,
5948 @UserIdInt int userId) {
5949 // Other argument checks are done in get/setWhitelistedRestrictedPermissions
5950 Preconditions.checkNotNull(permission);
5952 if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permission)) {
5956 final List<String> permissions = getWhitelistedRestrictedPermissions(packageName,
5957 whitelistFlags, userId);
5958 if (permissions != null && permissions.remove(permission)) {
5959 return setWhitelistedRestrictedPermissions(packageName, permissions,
5960 whitelistFlags, userId);
5965 private boolean setWhitelistedRestrictedPermissions(@NonNull String packageName,
5966 @Nullable List<String> permissions, @PermissionWhitelistFlags int whitelistFlag,
5967 @UserIdInt int userId) {
5968 Preconditions.checkNotNull(packageName);
5969 Preconditions.checkFlagsArgument(whitelistFlag,
5970 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
5971 | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
5972 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
5973 Preconditions.checkArgument(Integer.bitCount(whitelistFlag) == 1);
5974 Preconditions.checkArgumentNonNegative(userId, null);
5976 if (UserHandle.getCallingUserId() != userId) {
5977 mContext.enforceCallingOrSelfPermission(
5978 Manifest.permission.INTERACT_ACROSS_USERS,
5979 "setWhitelistedRestrictedPermissions for user " + userId);
5982 final PackageParser.Package pkg;
5984 synchronized (mPackages) {
5985 final PackageSetting packageSetting = mSettings.mPackages.get(packageName);
5986 if (packageSetting == null) {
5987 Slog.w(TAG, "Unknown package: " + packageName);
5991 pkg = packageSetting.pkg;
5993 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
5994 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
5995 == PackageManager.PERMISSION_GRANTED;
5996 final PackageSetting installerPackageSetting = mSettings.mPackages.get(
5997 packageSetting.installerPackageName);
5998 final boolean isCallerInstallerOnRecord = installerPackageSetting != null
5999 && UserHandle.isSameApp(installerPackageSetting.appId, Binder.getCallingUid());
6001 if ((whitelistFlag & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
6002 && !isCallerPrivileged) {
6003 throw new SecurityException("Modifying system whitelist requires "
6004 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
6007 if ((whitelistFlag & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
6008 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
6009 throw new SecurityException("Modifying upgrade whitelist requires"
6010 + " being installer on record or "
6011 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
6013 final List<String> whitelistedPermissions = getWhitelistedRestrictedPermissions(
6014 packageName, whitelistFlag, userId);
6015 if (permissions == null || permissions.isEmpty()) {
6016 if (whitelistedPermissions == null || whitelistedPermissions.isEmpty()) {
6020 // Only the system can add and remove while the installer can only remove.
6021 final int permissionCount = permissions.size();
6022 for (int i = 0; i < permissionCount; i++) {
6023 if ((whitelistedPermissions == null
6024 || !whitelistedPermissions.contains(permissions.get(i)))
6025 && !isCallerPrivileged) {
6026 throw new SecurityException("Adding to upgrade whitelist requires"
6027 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
6033 if ((whitelistFlag & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
6034 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
6035 throw new SecurityException("Modifying installer whitelist requires"
6036 + " being installer on record or "
6037 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
6041 if (filterAppAccessLPr(packageSetting, Binder.getCallingUid(),
6042 UserHandle.getCallingUserId())) {
6047 final long identity = Binder.clearCallingIdentity();
6049 mPermissionManager.setWhitelistedRestrictedPermissions(pkg,
6050 new int[]{userId}, permissions, Process.myUid(), whitelistFlag,
6051 mPermissionCallback);
6053 Binder.restoreCallingIdentity(identity);
6060 public boolean shouldShowRequestPermissionRationale(String permissionName,
6061 String packageName, int userId) {
6062 if (UserHandle.getCallingUserId() != userId) {
6063 mContext.enforceCallingPermission(
6064 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
6065 "canShowRequestPermissionRationale for user " + userId);
6068 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
6069 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
6073 if (checkPermission(permissionName, packageName, userId)
6074 == PackageManager.PERMISSION_GRANTED) {
6080 final long identity = Binder.clearCallingIdentity();
6082 flags = getPermissionFlags(permissionName,
6083 packageName, userId);
6085 Binder.restoreCallingIdentity(identity);
6088 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
6089 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
6090 | PackageManager.FLAG_PERMISSION_USER_FIXED;
6092 if ((flags & fixedFlags) != 0) {
6096 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
6100 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
6101 mContext.enforceCallingOrSelfPermission(
6102 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
6103 "addOnPermissionsChangeListener");
6105 synchronized (mPackages) {
6106 mOnPermissionChangeListeners.addListenerLocked(listener);
6111 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
6112 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6113 throw new SecurityException("Instant applications don't have access to this method");
6115 synchronized (mPackages) {
6116 mOnPermissionChangeListeners.removeListenerLocked(listener);
6121 public boolean isProtectedBroadcast(String actionName) {
6122 // allow instant applications
6123 synchronized (mProtectedBroadcasts) {
6124 if (mProtectedBroadcasts.contains(actionName)) {
6126 } else if (actionName != null) {
6127 // TODO: remove these terrible hacks
6128 if (actionName.startsWith("android.net.netmon.lingerExpired")
6129 || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
6130 || actionName.startsWith("com.android.internal.telephony.data-reconnect")
6131 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
6140 public int checkSignatures(String pkg1, String pkg2) {
6141 synchronized (mPackages) {
6142 final PackageParser.Package p1 = mPackages.get(pkg1);
6143 final PackageParser.Package p2 = mPackages.get(pkg2);
6144 if (p1 == null || p1.mExtras == null
6145 || p2 == null || p2.mExtras == null) {
6146 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6148 final int callingUid = Binder.getCallingUid();
6149 final int callingUserId = UserHandle.getUserId(callingUid);
6150 final PackageSetting ps1 = (PackageSetting) p1.mExtras;
6151 final PackageSetting ps2 = (PackageSetting) p2.mExtras;
6152 if (filterAppAccessLPr(ps1, callingUid, callingUserId)
6153 || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
6154 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6156 return compareSignatures(p1.mSigningDetails.signatures, p2.mSigningDetails.signatures);
6161 public int checkUidSignatures(int uid1, int uid2) {
6162 final int callingUid = Binder.getCallingUid();
6163 final int callingUserId = UserHandle.getUserId(callingUid);
6164 final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6165 // Map to base uids.
6166 final int appId1 = UserHandle.getAppId(uid1);
6167 final int appId2 = UserHandle.getAppId(uid2);
6169 synchronized (mPackages) {
6172 Object obj = mSettings.getSettingLPr(appId1);
6174 if (obj instanceof SharedUserSetting) {
6175 if (isCallerInstantApp) {
6176 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6178 s1 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
6179 } else if (obj instanceof PackageSetting) {
6180 final PackageSetting ps = (PackageSetting) obj;
6181 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6182 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6184 s1 = ps.signatures.mSigningDetails.signatures;
6186 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6189 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6191 obj = mSettings.getSettingLPr(appId2);
6193 if (obj instanceof SharedUserSetting) {
6194 if (isCallerInstantApp) {
6195 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6197 s2 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
6198 } else if (obj instanceof PackageSetting) {
6199 final PackageSetting ps = (PackageSetting) obj;
6200 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6201 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6203 s2 = ps.signatures.mSigningDetails.signatures;
6205 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6208 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6210 return compareSignatures(s1, s2);
6215 public boolean hasSigningCertificate(
6216 String packageName, byte[] certificate, @PackageManager.CertificateInputType int type) {
6218 synchronized (mPackages) {
6219 final PackageParser.Package p = mPackages.get(packageName);
6220 if (p == null || p.mExtras == null) {
6223 final int callingUid = Binder.getCallingUid();
6224 final int callingUserId = UserHandle.getUserId(callingUid);
6225 final PackageSetting ps = (PackageSetting) p.mExtras;
6226 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6230 case CERT_INPUT_RAW_X509:
6231 return p.mSigningDetails.hasCertificate(certificate);
6232 case CERT_INPUT_SHA256:
6233 return p.mSigningDetails.hasSha256Certificate(certificate);
6241 public boolean hasUidSigningCertificate(
6242 int uid, byte[] certificate, @PackageManager.CertificateInputType int type) {
6243 final int callingUid = Binder.getCallingUid();
6244 final int callingUserId = UserHandle.getUserId(callingUid);
6245 // Map to base uids.
6246 final int appId = UserHandle.getAppId(uid);
6248 synchronized (mPackages) {
6249 final PackageParser.SigningDetails signingDetails;
6250 final Object obj = mSettings.getSettingLPr(appId);
6252 if (obj instanceof SharedUserSetting) {
6253 final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6254 if (isCallerInstantApp) {
6257 signingDetails = ((SharedUserSetting)obj).signatures.mSigningDetails;
6258 } else if (obj instanceof PackageSetting) {
6259 final PackageSetting ps = (PackageSetting) obj;
6260 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6263 signingDetails = ps.signatures.mSigningDetails;
6271 case CERT_INPUT_RAW_X509:
6272 return signingDetails.hasCertificate(certificate);
6273 case CERT_INPUT_SHA256:
6274 return signingDetails.hasSha256Certificate(certificate);
6282 * This method should typically only be used when granting or revoking
6283 * permissions, since the app may immediately restart after this call.
6285 * If you're doing surgery on app code/data, use {@link PackageFreezer} to
6286 * guard your work against the app being relaunched.
6288 private void killUid(int appId, int userId, String reason) {
6289 final long identity = Binder.clearCallingIdentity();
6291 IActivityManager am = ActivityManager.getService();
6294 am.killUid(appId, userId, reason);
6295 } catch (RemoteException e) {
6296 /* ignore - same process */
6300 Binder.restoreCallingIdentity(identity);
6305 * If the database version for this type of package (internal storage or
6306 * external storage) is less than the version where package signatures
6307 * were updated, return true.
6309 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6310 return isCompatSignatureUpdateNeeded(getSettingsVersionForPackage(scannedPkg));
6313 private static boolean isCompatSignatureUpdateNeeded(VersionInfo ver) {
6314 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
6317 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6318 return isRecoverSignatureUpdateNeeded(getSettingsVersionForPackage(scannedPkg));
6321 private static boolean isRecoverSignatureUpdateNeeded(VersionInfo ver) {
6322 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
6326 public List<String> getAllPackages() {
6327 final int callingUid = Binder.getCallingUid();
6328 final int callingUserId = UserHandle.getUserId(callingUid);
6329 synchronized (mPackages) {
6330 if (canViewInstantApps(callingUid, callingUserId)) {
6331 return new ArrayList<>(mPackages.keySet());
6333 final String instantAppPkgName = getInstantAppPackageName(callingUid);
6334 final List<String> result = new ArrayList<>();
6335 if (instantAppPkgName != null) {
6336 // caller is an instant application; filter unexposed applications
6337 for (PackageParser.Package pkg : mPackages.values()) {
6338 if (!pkg.visibleToInstantApps) {
6341 result.add(pkg.packageName);
6344 // caller is a normal application; filter instant applications
6345 for (PackageParser.Package pkg : mPackages.values()) {
6346 final PackageSetting ps =
6347 pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
6349 && ps.getInstantApp(callingUserId)
6350 && !mInstantAppRegistry.isInstantAccessGranted(
6351 callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
6354 result.add(pkg.packageName);
6362 * <em>IMPORTANT:</em> Not all packages returned by this method may be known
6363 * to the system. There are two conditions in which this may occur:
6365 * <li>The package is on adoptable storage and the device has been removed</li>
6366 * <li>The package is being removed and the internal structures are partially updated</li>
6368 * The second is an artifact of the current data structures and should be fixed. See
6369 * b/111075456 for one such instance.
6372 public String[] getPackagesForUid(int uid) {
6373 final int callingUid = Binder.getCallingUid();
6374 final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6375 final int userId = UserHandle.getUserId(uid);
6376 final int appId = UserHandle.getAppId(uid);
6378 synchronized (mPackages) {
6379 final Object obj = mSettings.getSettingLPr(appId);
6380 if (obj instanceof SharedUserSetting) {
6381 if (isCallerInstantApp) {
6384 final SharedUserSetting sus = (SharedUserSetting) obj;
6385 final int N = sus.packages.size();
6386 String[] res = new String[N];
6387 final Iterator<PackageSetting> it = sus.packages.iterator();
6389 while (it.hasNext()) {
6390 PackageSetting ps = it.next();
6391 if (ps.getInstalled(userId)) {
6394 res = ArrayUtils.removeElement(String.class, res, res[i]);
6398 } else if (obj instanceof PackageSetting) {
6399 final PackageSetting ps = (PackageSetting) obj;
6400 if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
6401 return new String[]{ps.name};
6409 public String getNameForUid(int uid) {
6410 final int callingUid = Binder.getCallingUid();
6411 if (getInstantAppPackageName(callingUid) != null) {
6414 final int appId = UserHandle.getAppId(uid);
6415 synchronized (mPackages) {
6416 final Object obj = mSettings.getSettingLPr(appId);
6417 if (obj instanceof SharedUserSetting) {
6418 final SharedUserSetting sus = (SharedUserSetting) obj;
6419 return sus.name + ":" + sus.userId;
6420 } else if (obj instanceof PackageSetting) {
6421 final PackageSetting ps = (PackageSetting) obj;
6422 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6432 public String[] getNamesForUids(int[] uids) {
6433 if (uids == null || uids.length == 0) {
6436 final int callingUid = Binder.getCallingUid();
6437 if (getInstantAppPackageName(callingUid) != null) {
6440 final String[] names = new String[uids.length];
6441 synchronized (mPackages) {
6442 for (int i = uids.length - 1; i >= 0; i--) {
6443 final int appId = UserHandle.getAppId(uids[i]);
6444 final Object obj = mSettings.getSettingLPr(appId);
6445 if (obj instanceof SharedUserSetting) {
6446 final SharedUserSetting sus = (SharedUserSetting) obj;
6447 names[i] = "shared:" + sus.name;
6448 } else if (obj instanceof PackageSetting) {
6449 final PackageSetting ps = (PackageSetting) obj;
6450 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6464 public int getUidForSharedUser(String sharedUserName) {
6465 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6468 if (sharedUserName == null) {
6472 synchronized (mPackages) {
6473 SharedUserSetting suid;
6475 suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
6479 } catch (PackageManagerException ignore) {
6480 // can't happen, but, still need to catch it
6487 public int getFlagsForUid(int uid) {
6488 final int callingUid = Binder.getCallingUid();
6489 if (getInstantAppPackageName(callingUid) != null) {
6492 final int appId = UserHandle.getAppId(uid);
6493 synchronized (mPackages) {
6494 final Object obj = mSettings.getSettingLPr(appId);
6495 if (obj instanceof SharedUserSetting) {
6496 final SharedUserSetting sus = (SharedUserSetting) obj;
6497 return sus.pkgFlags;
6498 } else if (obj instanceof PackageSetting) {
6499 final PackageSetting ps = (PackageSetting) obj;
6500 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6510 public int getPrivateFlagsForUid(int uid) {
6511 final int callingUid = Binder.getCallingUid();
6512 if (getInstantAppPackageName(callingUid) != null) {
6515 final int appId = UserHandle.getAppId(uid);
6516 synchronized (mPackages) {
6517 final Object obj = mSettings.getSettingLPr(appId);
6518 if (obj instanceof SharedUserSetting) {
6519 final SharedUserSetting sus = (SharedUserSetting) obj;
6520 return sus.pkgPrivateFlags;
6521 } else if (obj instanceof PackageSetting) {
6522 final PackageSetting ps = (PackageSetting) obj;
6523 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6526 return ps.pkgPrivateFlags;
6533 public boolean isUidPrivileged(int uid) {
6534 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6537 final int appId = UserHandle.getAppId(uid);
6539 synchronized (mPackages) {
6540 final Object obj = mSettings.getSettingLPr(appId);
6541 if (obj instanceof SharedUserSetting) {
6542 final SharedUserSetting sus = (SharedUserSetting) obj;
6543 final Iterator<PackageSetting> it = sus.packages.iterator();
6544 while (it.hasNext()) {
6545 if (it.next().isPrivileged()) {
6549 } else if (obj instanceof PackageSetting) {
6550 final PackageSetting ps = (PackageSetting) obj;
6551 return ps.isPrivileged();
6558 public String[] getAppOpPermissionPackages(String permName) {
6559 return mPermissionManager.getAppOpPermissionPackages(permName);
6563 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
6564 int flags, int userId) {
6565 return resolveIntentInternal(intent, resolvedType, flags, userId, false,
6566 Binder.getCallingUid());
6570 * Normally instant apps can only be resolved when they're visible to the caller.
6571 * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
6572 * since we need to allow the system to start any installed application.
6574 private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
6575 int flags, int userId, boolean resolveForStart, int filterCallingUid) {
6577 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
6579 if (!sUserManager.exists(userId)) return null;
6580 final int callingUid = Binder.getCallingUid();
6581 flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart);
6582 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
6583 false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
6585 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6586 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
6587 flags, filterCallingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
6588 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6590 final ResolveInfo bestChoice =
6591 chooseBestActivity(intent, resolvedType, flags, query, userId);
6594 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6599 public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
6600 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
6601 throw new SecurityException(
6602 "findPersistentPreferredActivity can only be run by the system");
6604 if (!sUserManager.exists(userId)) {
6607 final int callingUid = Binder.getCallingUid();
6608 intent = updateIntentForResolve(intent);
6609 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
6610 final int flags = updateFlagsForResolve(
6611 0, userId, intent, callingUid, false /*includeInstantApps*/);
6612 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6614 synchronized (mPackages) {
6615 return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
6621 public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
6622 IntentFilter filter, int match, ComponentName activity) {
6623 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6626 final int userId = UserHandle.getCallingUserId();
6627 if (DEBUG_PREFERRED) {
6628 Log.v(TAG, "setLastChosenActivity intent=" + intent
6629 + " resolvedType=" + resolvedType
6631 + " filter=" + filter
6633 + " activity=" + activity);
6634 filter.dump(new PrintStreamPrinter(System.out), " ");
6636 intent.setComponent(null);
6637 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6639 // Find any earlier preferred or last chosen entries and nuke them
6640 findPreferredActivityNotLocked(
6641 intent, resolvedType, flags, query, 0, false, true, false, userId);
6642 // Add the new activity as the last chosen for this filter
6643 addPreferredActivityInternal(filter, match, null, activity, false, userId,
6644 "Setting last chosen");
6648 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
6649 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6652 final int userId = UserHandle.getCallingUserId();
6653 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
6654 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6656 return findPreferredActivityNotLocked(
6657 intent, resolvedType, flags, query, 0, false, false, false, userId);
6661 * Returns whether or not instant apps have been disabled remotely.
6663 private boolean areWebInstantAppsDisabled(int userId) {
6664 return mWebInstantAppsDisabled.get(userId);
6667 private boolean isInstantAppResolutionAllowed(
6668 Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6669 boolean skipPackageCheck) {
6670 if (mInstantAppResolverConnection == null) {
6673 if (mInstantAppInstallerActivity == null) {
6676 if (intent.getComponent() != null) {
6679 if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6682 if (!skipPackageCheck && intent.getPackage() != null) {
6685 if (!intent.isWebIntent()) {
6686 // for non web intents, we should not resolve externally if an app already exists to
6687 // handle it or if the caller didn't explicitly request it.
6688 if ((resolvedActivities != null && resolvedActivities.size() != 0)
6689 || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) == 0) {
6693 if (intent.getData() == null || TextUtils.isEmpty(intent.getData().getHost())) {
6695 } else if (areWebInstantAppsDisabled(userId)) {
6699 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6700 // Or if there's already an ephemeral app installed that handles the action
6701 synchronized (mPackages) {
6702 final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6703 for (int n = 0; n < count; n++) {
6704 final ResolveInfo info = resolvedActivities.get(n);
6705 final String packageName = info.activityInfo.packageName;
6706 final PackageSetting ps = mSettings.mPackages.get(packageName);
6708 // only check domain verification status if the app is not a browser
6709 if (!info.handleAllWebDataURI) {
6710 // Try to get the status from User settings first
6711 final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6712 final int status = (int) (packedStatus >> 32);
6713 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6714 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6715 if (DEBUG_INSTANT) {
6716 Slog.v(TAG, "DENY instant app;"
6717 + " pkg: " + packageName + ", status: " + status);
6722 if (ps.getInstantApp(userId)) {
6723 if (DEBUG_INSTANT) {
6724 Slog.v(TAG, "DENY instant app installed;"
6725 + " pkg: " + packageName);
6732 // We've exhausted all ways to deny ephemeral application; let the system look for them.
6736 private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6737 Intent origIntent, String resolvedType, String callingPackage,
6738 Bundle verificationBundle, int userId) {
6739 final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6740 new InstantAppRequest(responseObj, origIntent, resolvedType,
6741 callingPackage, userId, verificationBundle, false /*resolveForStart*/));
6742 mHandler.sendMessage(msg);
6745 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6746 int flags, List<ResolveInfo> query, int userId) {
6747 if (query != null) {
6748 final int N = query.size();
6750 return query.get(0);
6752 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6753 // If there is more than one activity with the same priority,
6754 // then let the user decide between them.
6755 ResolveInfo r0 = query.get(0);
6756 ResolveInfo r1 = query.get(1);
6757 if (DEBUG_INTENT_MATCHING || debug) {
6758 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6759 + r1.activityInfo.name + "=" + r1.priority);
6761 // If the first activity has a higher priority, or a different
6762 // default, then it is always desirable to pick it.
6763 if (r0.priority != r1.priority
6764 || r0.preferredOrder != r1.preferredOrder
6765 || r0.isDefault != r1.isDefault) {
6766 return query.get(0);
6768 // If we have saved a preference for a preferred activity for
6769 // this Intent, use that.
6770 ResolveInfo ri = findPreferredActivityNotLocked(intent, resolvedType,
6771 flags, query, r0.priority, true, false, debug, userId);
6775 // If we have an ephemeral app, use it
6776 for (int i = 0; i < N; i++) {
6778 if (ri.activityInfo.applicationInfo.isInstantApp()) {
6779 final String packageName = ri.activityInfo.packageName;
6780 final PackageSetting ps = mSettings.mPackages.get(packageName);
6781 final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6782 final int status = (int)(packedStatus >> 32);
6783 if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6788 ri = new ResolveInfo(mResolveInfo);
6789 ri.activityInfo = new ActivityInfo(ri.activityInfo);
6790 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6791 // If all of the options come from the same package, show the application's
6792 // label and icon instead of the generic resolver's.
6793 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6794 // and then throw away the ResolveInfo itself, meaning that the caller loses
6795 // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6796 // a fallback for this case; we only set the target package's resources on
6797 // the ResolveInfo, not the ActivityInfo.
6798 final String intentPackage = intent.getPackage();
6799 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6800 final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6801 ri.resolvePackageName = intentPackage;
6802 if (userNeedsBadging(userId)) {
6803 ri.noResourceId = true;
6805 ri.icon = appi.icon;
6807 ri.iconResourceId = appi.icon;
6808 ri.labelRes = appi.labelRes;
6810 ri.activityInfo.applicationInfo = new ApplicationInfo(
6811 ri.activityInfo.applicationInfo);
6813 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6814 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6816 // Make sure that the resolver is displayable in car mode
6817 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6818 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6826 * Return true if the given list is not empty and all of its contents have
6827 * an activityInfo with the given package name.
6829 private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6830 if (ArrayUtils.isEmpty(list)) {
6833 for (int i = 0, N = list.size(); i < N; i++) {
6834 final ResolveInfo ri = list.get(i);
6835 final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6836 if (ai == null || !packageName.equals(ai.packageName)) {
6843 @GuardedBy("mPackages")
6844 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6845 int flags, List<ResolveInfo> query, boolean debug, int userId) {
6846 final int N = query.size();
6847 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6849 // Get the list of persistent preferred activities that handle the intent
6850 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6851 List<PersistentPreferredActivity> pprefs = ppir != null
6852 ? ppir.queryIntent(intent, resolvedType,
6853 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6856 if (pprefs != null && pprefs.size() > 0) {
6857 final int M = pprefs.size();
6858 for (int i=0; i<M; i++) {
6859 final PersistentPreferredActivity ppa = pprefs.get(i);
6860 if (DEBUG_PREFERRED || debug) {
6861 Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6862 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6863 + "\n component=" + ppa.mComponent);
6864 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6866 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6867 flags | MATCH_DISABLED_COMPONENTS, userId);
6868 if (DEBUG_PREFERRED || debug) {
6869 Slog.v(TAG, "Found persistent preferred activity:");
6871 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6873 Slog.v(TAG, " null");
6877 // This previously registered persistent preferred activity
6878 // component is no longer known. Ignore it and do NOT remove it.
6881 for (int j=0; j<N; j++) {
6882 final ResolveInfo ri = query.get(j);
6883 if (!ri.activityInfo.applicationInfo.packageName
6884 .equals(ai.applicationInfo.packageName)) {
6887 if (!ri.activityInfo.name.equals(ai.name)) {
6890 // Found a persistent preference that can handle the intent.
6891 if (DEBUG_PREFERRED || debug) {
6892 Slog.v(TAG, "Returning persistent preferred activity: " +
6893 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6902 private boolean isHomeIntent(Intent intent) {
6903 return ACTION_MAIN.equals(intent.getAction())
6904 && intent.hasCategory(CATEGORY_HOME)
6905 && intent.hasCategory(CATEGORY_DEFAULT);
6908 // TODO: handle preferred activities missing while user has amnesia
6909 /** <b>must not hold {@link #mPackages}</b> */
6910 ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
6911 List<ResolveInfo> query, int priority, boolean always,
6912 boolean removeMatches, boolean debug, int userId) {
6913 if (Thread.holdsLock(mPackages)) {
6914 Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
6915 + " is holding mPackages", new Throwable());
6917 if (!sUserManager.exists(userId)) return null;
6918 final int callingUid = Binder.getCallingUid();
6919 // Do NOT hold the packages lock; this calls up into the settings provider which
6920 // could cause a deadlock.
6921 final boolean isDeviceProvisioned =
6922 android.provider.Settings.Global.getInt(mContext.getContentResolver(),
6923 android.provider.Settings.Global.DEVICE_PROVISIONED, 0) == 1;
6924 flags = updateFlagsForResolve(
6925 flags, userId, intent, callingUid, false /*includeInstantApps*/);
6926 intent = updateIntentForResolve(intent);
6928 synchronized (mPackages) {
6929 // Try to find a matching persistent preferred activity.
6930 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6933 // If a persistent preferred activity matched, use it.
6938 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6939 // Get the list of preferred activities that handle the intent
6940 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6941 List<PreferredActivity> prefs = pir != null
6942 ? pir.queryIntent(intent, resolvedType,
6943 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6946 if (prefs != null && prefs.size() > 0) {
6947 boolean changed = false;
6949 // First figure out how good the original match set is.
6950 // We will only allow preferred activities that came
6951 // from the same match quality.
6954 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6956 final int N = query.size();
6957 for (int j=0; j<N; j++) {
6958 final ResolveInfo ri = query.get(j);
6959 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6960 + ": 0x" + Integer.toHexString(match));
6961 if (ri.match > match) {
6966 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6967 + Integer.toHexString(match));
6969 match &= IntentFilter.MATCH_CATEGORY_MASK;
6970 final int M = prefs.size();
6971 for (int i=0; i<M; i++) {
6972 final PreferredActivity pa = prefs.get(i);
6973 if (DEBUG_PREFERRED || debug) {
6974 Slog.v(TAG, "Checking PreferredActivity ds="
6975 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6976 + "\n component=" + pa.mPref.mComponent);
6977 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6979 if (pa.mPref.mMatch != match) {
6980 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6981 + Integer.toHexString(pa.mPref.mMatch));
6984 // If it's not an "always" type preferred activity and that's what we're
6985 // looking for, skip it.
6986 if (always && !pa.mPref.mAlways) {
6987 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6990 final ActivityInfo ai = getActivityInfo(
6991 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6992 | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6994 if (DEBUG_PREFERRED || debug) {
6995 Slog.v(TAG, "Found preferred activity:");
6997 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
6999 Slog.v(TAG, " null");
7002 final boolean excludeSetupWizardHomeActivity = isHomeIntent(intent)
7003 && !isDeviceProvisioned;
7005 // Do not remove launcher's preferred activity during SetupWizard
7006 // due to it may not install yet
7007 if (excludeSetupWizardHomeActivity) {
7011 // This previously registered preferred activity
7012 // component is no longer known. Most likely an update
7013 // to the app was installed and in the new version this
7014 // component no longer exists. Clean it up by removing
7015 // it from the preferred activities list, and skip it.
7016 Slog.w(TAG, "Removing dangling preferred activity: "
7017 + pa.mPref.mComponent);
7018 pir.removeFilter(pa);
7022 for (int j=0; j<N; j++) {
7023 final ResolveInfo ri = query.get(j);
7024 if (!ri.activityInfo.applicationInfo.packageName
7025 .equals(ai.applicationInfo.packageName)) {
7028 if (!ri.activityInfo.name.equals(ai.name)) {
7032 if (removeMatches) {
7033 pir.removeFilter(pa);
7035 if (DEBUG_PREFERRED) {
7036 Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
7041 // Okay we found a previously set preferred or last chosen app.
7042 // If the result set is different from when this
7043 // was created, and is not a subset of the preferred set, we need to
7044 // clear it and re-ask the user their preference, if we're looking for
7045 // an "always" type entry.
7047 if (always && !pa.mPref.sameSet(query, excludeSetupWizardHomeActivity)) {
7048 if (pa.mPref.isSuperset(query, excludeSetupWizardHomeActivity)) {
7049 if (!excludeSetupWizardHomeActivity) {
7050 // some components of the set are no longer present in
7051 // the query, but the preferred activity can still be reused
7052 if (DEBUG_PREFERRED) {
7053 Slog.i(TAG, "Result set changed, but PreferredActivity"
7054 + " is still valid as only non-preferred"
7055 + " components were removed for " + intent
7056 + " type " + resolvedType);
7058 // remove obsolete components and re-add the up-to-date
7060 PreferredActivity freshPa = new PreferredActivity(pa,
7062 pa.mPref.discardObsoleteComponents(query),
7063 pa.mPref.mComponent,
7065 pir.removeFilter(pa);
7066 pir.addFilter(freshPa);
7069 if (DEBUG_PREFERRED) {
7070 Slog.i(TAG, "Do not remove preferred activity for launcher"
7071 + " during SetupWizard");
7076 "Result set changed, dropping preferred activity for "
7077 + intent + " type " + resolvedType);
7078 if (DEBUG_PREFERRED) {
7079 Slog.v(TAG, "Removing preferred activity since set changed "
7080 + pa.mPref.mComponent);
7082 pir.removeFilter(pa);
7083 // Re-add the filter as a "last chosen" entry (!always)
7084 PreferredActivity lastChosen = new PreferredActivity(
7085 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
7086 pir.addFilter(lastChosen);
7092 // Yay! Either the set matched or we're looking for the last chosen
7093 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
7094 + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
7100 if (DEBUG_PREFERRED) {
7101 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
7103 scheduleWritePackageRestrictionsLocked(userId);
7108 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
7113 * Returns if intent can be forwarded from the sourceUserId to the targetUserId
7116 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
7118 mContext.enforceCallingOrSelfPermission(
7119 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
7120 List<CrossProfileIntentFilter> matches =
7121 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
7122 if (matches != null) {
7123 int size = matches.size();
7124 for (int i = 0; i < size; i++) {
7125 if (matches.get(i).getTargetUserId() == targetUserId) return true;
7128 if (intent.hasWebURI()) {
7129 // cross-profile app linking works only towards the parent.
7130 final int callingUid = Binder.getCallingUid();
7131 final UserInfo parent = getProfileParent(sourceUserId);
7132 synchronized(mPackages) {
7133 int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
7134 false /*includeInstantApps*/);
7135 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
7136 intent, resolvedType, flags, sourceUserId, parent.id);
7137 return xpDomainInfo != null;
7143 private UserInfo getProfileParent(int userId) {
7144 final long identity = Binder.clearCallingIdentity();
7146 return sUserManager.getProfileParent(userId);
7148 Binder.restoreCallingIdentity(identity);
7152 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
7153 String resolvedType, int userId) {
7154 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
7155 if (resolver != null) {
7156 return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
7162 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
7163 String resolvedType, int flags, int userId) {
7165 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
7167 return new ParceledListSlice<>(
7168 queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
7170 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7175 * Returns the package name of the calling Uid if it's an instant app. If it isn't
7176 * instant, returns {@code null}.
7178 private String getInstantAppPackageName(int callingUid) {
7179 synchronized (mPackages) {
7180 // If the caller is an isolated app use the owner's uid for the lookup.
7181 if (Process.isIsolated(callingUid)) {
7182 callingUid = mIsolatedOwners.get(callingUid);
7184 final int appId = UserHandle.getAppId(callingUid);
7185 final Object obj = mSettings.getSettingLPr(appId);
7186 if (obj instanceof PackageSetting) {
7187 final PackageSetting ps = (PackageSetting) obj;
7188 final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
7189 return isInstantApp ? ps.pkg.packageName : null;
7195 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
7196 String resolvedType, int flags, int userId) {
7197 return queryIntentActivitiesInternal(
7198 intent, resolvedType, flags, Binder.getCallingUid(), userId,
7199 false /*resolveForStart*/, true /*allowDynamicSplits*/);
7202 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
7203 String resolvedType, int flags, int filterCallingUid, int userId,
7204 boolean resolveForStart, boolean allowDynamicSplits) {
7205 if (!sUserManager.exists(userId)) return Collections.emptyList();
7206 final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
7207 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7208 false /* requireFullPermission */, false /* checkShell */,
7209 "query intent activities");
7210 final String pkgName = intent.getPackage();
7211 ComponentName comp = intent.getComponent();
7213 if (intent.getSelector() != null) {
7214 intent = intent.getSelector();
7215 comp = intent.getComponent();
7219 flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
7220 comp != null || pkgName != null /*onlyExposedExplicitly*/);
7222 final List<ResolveInfo> list = new ArrayList<>(1);
7223 final ActivityInfo ai = getActivityInfo(comp, flags, userId);
7225 // When specifying an explicit component, we prevent the activity from being
7226 // used when either 1) the calling package is normal and the activity is within
7227 // an ephemeral application or 2) the calling package is ephemeral and the
7228 // activity is not visible to ephemeral applications.
7229 final boolean matchInstantApp =
7230 (flags & PackageManager.MATCH_INSTANT) != 0;
7231 final boolean matchVisibleToInstantAppOnly =
7232 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7233 final boolean matchExplicitlyVisibleOnly =
7234 (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7235 final boolean isCallerInstantApp =
7236 instantAppPkgName != null;
7237 final boolean isTargetSameInstantApp =
7238 comp.getPackageName().equals(instantAppPkgName);
7239 final boolean isTargetInstantApp =
7240 (ai.applicationInfo.privateFlags
7241 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7242 final boolean isTargetVisibleToInstantApp =
7243 (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7244 final boolean isTargetExplicitlyVisibleToInstantApp =
7245 isTargetVisibleToInstantApp
7246 && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7247 final boolean isTargetHiddenFromInstantApp =
7248 !isTargetVisibleToInstantApp
7249 || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7250 final boolean blockResolution =
7251 !isTargetSameInstantApp
7252 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7253 || (matchVisibleToInstantAppOnly && isCallerInstantApp
7254 && isTargetHiddenFromInstantApp));
7255 if (!blockResolution) {
7256 final ResolveInfo ri = new ResolveInfo();
7257 ri.activityInfo = ai;
7261 return applyPostResolutionFilter(
7262 list, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,
7267 boolean sortResult = false;
7268 boolean addInstant = false;
7269 List<ResolveInfo> result;
7270 synchronized (mPackages) {
7271 if (pkgName == null) {
7272 List<CrossProfileIntentFilter> matchingFilters =
7273 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
7274 // Check for results that need to skip the current profile.
7275 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
7276 resolvedType, flags, userId);
7277 if (xpResolveInfo != null) {
7278 List<ResolveInfo> xpResult = new ArrayList<>(1);
7279 xpResult.add(xpResolveInfo);
7280 return applyPostResolutionFilter(
7281 filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
7282 allowDynamicSplits, filterCallingUid, resolveForStart, userId, intent);
7285 // Check for results in the current profile.
7286 result = filterIfNotSystemUser(mComponentResolver.queryActivities(
7287 intent, resolvedType, flags, userId), userId);
7288 addInstant = isInstantAppResolutionAllowed(intent, result, userId,
7289 false /*skipPackageCheck*/);
7290 // Check for cross profile results.
7291 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
7292 xpResolveInfo = queryCrossProfileIntents(
7293 matchingFilters, intent, resolvedType, flags, userId,
7294 hasNonNegativePriorityResult);
7295 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
7296 boolean isVisibleToUser = filterIfNotSystemUser(
7297 Collections.singletonList(xpResolveInfo), userId).size() > 0;
7298 if (isVisibleToUser) {
7299 result.add(xpResolveInfo);
7303 if (intent.hasWebURI()) {
7304 CrossProfileDomainInfo xpDomainInfo = null;
7305 final UserInfo parent = getProfileParent(userId);
7306 if (parent != null) {
7307 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
7308 flags, userId, parent.id);
7310 if (xpDomainInfo != null) {
7311 if (xpResolveInfo != null) {
7312 // If we didn't remove it, the cross-profile ResolveInfo would be twice
7314 result.remove(xpResolveInfo);
7316 if (result.size() == 0 && !addInstant) {
7317 // No result in current profile, but found candidate in parent user.
7318 // And we are not going to add emphemeral app, so we can return the
7319 // result straight away.
7320 result.add(xpDomainInfo.resolveInfo);
7321 return applyPostResolutionFilter(result, instantAppPkgName,
7322 allowDynamicSplits, filterCallingUid, resolveForStart, userId,
7325 } else if (result.size() <= 1 && !addInstant) {
7326 // No result in parent user and <= 1 result in current profile, and we
7327 // are not going to add emphemeral app, so we can return the result without
7328 // further processing.
7329 return applyPostResolutionFilter(result, instantAppPkgName,
7330 allowDynamicSplits, filterCallingUid, resolveForStart, userId,
7333 // We have more than one candidate (combining results from current and parent
7334 // profile), so we need filtering and sorting.
7335 result = filterCandidatesWithDomainPreferredActivitiesLPr(
7336 intent, flags, result, xpDomainInfo, userId);
7340 final PackageParser.Package pkg = mPackages.get(pkgName);
7343 result = filterIfNotSystemUser(mComponentResolver.queryActivities(
7344 intent, resolvedType, flags, pkg.activities, userId), userId);
7346 if (result == null || result.size() == 0) {
7347 // the caller wants to resolve for a particular package; however, there
7348 // were no installed results, so, try to find an ephemeral result
7349 addInstant = isInstantAppResolutionAllowed(
7350 intent, null /*result*/, userId, true /*skipPackageCheck*/);
7351 if (result == null) {
7352 result = new ArrayList<>();
7358 result = maybeAddInstantAppInstaller(
7359 result, intent, resolvedType, flags, userId, resolveForStart);
7362 Collections.sort(result, RESOLVE_PRIORITY_SORTER);
7364 return applyPostResolutionFilter(
7365 result, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,
7369 private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
7370 String resolvedType, int flags, int userId, boolean resolveForStart) {
7371 // first, check to see if we've got an instant app already installed
7372 final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
7373 ResolveInfo localInstantApp = null;
7374 boolean blockResolution = false;
7375 if (!alreadyResolvedLocally) {
7376 final List<ResolveInfo> instantApps = mComponentResolver.queryActivities(
7380 | PackageManager.GET_RESOLVED_FILTER
7381 | PackageManager.MATCH_INSTANT
7382 | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
7384 for (int i = instantApps.size() - 1; i >= 0; --i) {
7385 final ResolveInfo info = instantApps.get(i);
7386 final String packageName = info.activityInfo.packageName;
7387 final PackageSetting ps = mSettings.mPackages.get(packageName);
7388 if (ps.getInstantApp(userId)) {
7389 final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7390 final int status = (int)(packedStatus >> 32);
7391 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7392 // there's a local instant application installed, but, the user has
7393 // chosen to never use it; skip resolution and don't acknowledge
7394 // an instant application is even available
7395 if (DEBUG_INSTANT) {
7396 Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
7398 blockResolution = true;
7401 // we have a locally installed instant application; skip resolution
7402 // but acknowledge there's an instant application available
7403 if (DEBUG_INSTANT) {
7404 Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
7406 localInstantApp = info;
7412 // no app installed, let's see if one's available
7413 AuxiliaryResolveInfo auxiliaryResponse = null;
7414 if (!blockResolution) {
7415 if (localInstantApp == null) {
7416 // we don't have an instant app locally, resolve externally
7417 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
7418 final InstantAppRequest requestObject = new InstantAppRequest(
7419 null /*responseObj*/, intent /*origIntent*/, resolvedType,
7420 null /*callingPackage*/, userId, null /*verificationBundle*/,
7422 auxiliaryResponse = InstantAppResolver.doInstantAppResolutionPhaseOne(
7423 mInstantAppResolverConnection, requestObject);
7424 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7426 // we have an instant application locally, but, we can't admit that since
7427 // callers shouldn't be able to determine prior browsing. create a dummy
7428 // auxiliary response so the downstream code behaves as if there's an
7429 // instant application available externally. when it comes time to start
7430 // the instant application, we'll do the right thing.
7431 final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
7432 auxiliaryResponse = new AuxiliaryResolveInfo(null /* failureActivity */,
7433 ai.packageName, ai.longVersionCode, null /* splitName */);
7436 if (intent.isWebIntent() && auxiliaryResponse == null) {
7439 final PackageSetting ps = mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
7441 || !ps.readUserState(userId).isEnabled(mInstantAppInstallerActivity, 0)) {
7444 final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
7445 ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
7446 mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
7447 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7448 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7449 // add a non-generic filter
7450 ephemeralInstaller.filter = new IntentFilter();
7451 if (intent.getAction() != null) {
7452 ephemeralInstaller.filter.addAction(intent.getAction());
7454 if (intent.getData() != null && intent.getData().getPath() != null) {
7455 ephemeralInstaller.filter.addDataPath(
7456 intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
7458 ephemeralInstaller.isInstantAppAvailable = true;
7459 // make sure this resolver is the default
7460 ephemeralInstaller.isDefault = true;
7461 ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
7462 if (DEBUG_INSTANT) {
7463 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7466 result.add(ephemeralInstaller);
7470 private static class CrossProfileDomainInfo {
7471 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
7472 ResolveInfo resolveInfo;
7473 /* Best domain verification status of the activities found in the other profile */
7474 int bestDomainVerificationStatus;
7477 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
7478 String resolvedType, int flags, int sourceUserId, int parentUserId) {
7479 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
7483 List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent,
7484 resolvedType, flags, parentUserId);
7486 if (resultTargetUser == null || resultTargetUser.isEmpty()) {
7489 CrossProfileDomainInfo result = null;
7490 int size = resultTargetUser.size();
7491 for (int i = 0; i < size; i++) {
7492 ResolveInfo riTargetUser = resultTargetUser.get(i);
7493 // Intent filter verification is only for filters that specify a host. So don't return
7494 // those that handle all web uris.
7495 if (riTargetUser.handleAllWebDataURI) {
7498 String packageName = riTargetUser.activityInfo.packageName;
7499 PackageSetting ps = mSettings.mPackages.get(packageName);
7503 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
7504 int status = (int)(verificationState >> 32);
7505 if (result == null) {
7506 result = new CrossProfileDomainInfo();
7507 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
7508 sourceUserId, parentUserId);
7509 result.bestDomainVerificationStatus = status;
7511 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
7512 result.bestDomainVerificationStatus);
7515 // Don't consider matches with status NEVER across profiles.
7516 if (result != null && result.bestDomainVerificationStatus
7517 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7524 * Verification statuses are ordered from the worse to the best, except for
7525 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
7527 private int bestDomainVerificationStatus(int status1, int status2) {
7528 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7531 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7534 return (int) MathUtils.max(status1, status2);
7537 private boolean isUserEnabled(int userId) {
7538 long callingId = Binder.clearCallingIdentity();
7540 UserInfo userInfo = sUserManager.getUserInfo(userId);
7541 return userInfo != null && userInfo.isEnabled();
7543 Binder.restoreCallingIdentity(callingId);
7548 * Filter out activities with systemUserOnly flag set, when current user is not System.
7550 * @return filtered list
7552 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
7553 if (userId == UserHandle.USER_SYSTEM) {
7554 return resolveInfos;
7556 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7557 ResolveInfo info = resolveInfos.get(i);
7558 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
7559 resolveInfos.remove(i);
7562 return resolveInfos;
7566 * Filters out ephemeral activities.
7567 * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
7568 * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
7570 * @param resolveInfos The pre-filtered list of resolved activities
7571 * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
7574 * @return A filtered list of resolved activities.
7576 private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
7577 String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
7578 boolean resolveForStart, int userId, Intent intent) {
7579 final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled(userId);
7580 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7581 final ResolveInfo info = resolveInfos.get(i);
7582 // remove locally resolved instant app web results when disabled
7583 if (info.isInstantAppAvailable && blockInstant) {
7584 resolveInfos.remove(i);
7587 // allow activities that are defined in the provided package
7588 if (allowDynamicSplits
7589 && info.activityInfo != null
7590 && info.activityInfo.splitName != null
7591 && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
7592 info.activityInfo.splitName)) {
7593 if (mInstantAppInstallerActivity == null) {
7594 if (DEBUG_INSTALL) {
7595 Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
7597 resolveInfos.remove(i);
7600 if (blockInstant && isInstantApp(info.activityInfo.packageName, userId)) {
7601 resolveInfos.remove(i);
7604 // requested activity is defined in a split that hasn't been installed yet.
7605 // add the installer to the resolve list
7606 if (DEBUG_INSTALL) {
7607 Slog.v(TAG, "Adding installer to the ResolveInfo list");
7609 final ResolveInfo installerInfo = new ResolveInfo(
7610 mInstantAppInstallerInfo);
7611 final ComponentName installFailureActivity = findInstallFailureActivity(
7612 info.activityInfo.packageName, filterCallingUid, userId);
7613 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7614 installFailureActivity,
7615 info.activityInfo.packageName,
7616 info.activityInfo.applicationInfo.longVersionCode,
7617 info.activityInfo.splitName);
7618 // add a non-generic filter
7619 installerInfo.filter = new IntentFilter();
7621 // This resolve info may appear in the chooser UI, so let us make it
7622 // look as the one it replaces as far as the user is concerned which
7623 // requires loading the correct label and icon for the resolve info.
7624 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7625 installerInfo.labelRes = info.resolveLabelResId();
7626 installerInfo.icon = info.resolveIconResId();
7627 installerInfo.isInstantAppAvailable = true;
7628 resolveInfos.set(i, installerInfo);
7631 // caller is a full app, don't need to apply any other filtering
7632 if (ephemeralPkgName == null) {
7634 } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
7635 // caller is same app; don't need to apply any other filtering
7637 } else if (resolveForStart
7638 && (intent.isWebIntent()
7639 || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0)
7640 && intent.getPackage() == null
7641 && intent.getComponent() == null) {
7642 // ephemeral apps can launch other ephemeral apps indirectly
7645 // allow activities that have been explicitly exposed to ephemeral apps
7646 final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
7648 && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7651 resolveInfos.remove(i);
7653 return resolveInfos;
7657 * Returns the activity component that can handle install failures.
7658 * <p>By default, the instant application installer handles failures. However, an
7659 * application may want to handle failures on its own. Applications do this by
7660 * creating an activity with an intent filter that handles the action
7661 * {@link Intent#ACTION_INSTALL_FAILURE}.
7663 private @Nullable ComponentName findInstallFailureActivity(
7664 String packageName, int filterCallingUid, int userId) {
7665 final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
7666 failureActivityIntent.setPackage(packageName);
7667 // IMPORTANT: disallow dynamic splits to avoid an infinite loop
7668 final List<ResolveInfo> result = queryIntentActivitiesInternal(
7669 failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
7670 false /*resolveForStart*/, false /*allowDynamicSplits*/);
7671 final int NR = result.size();
7673 for (int i = 0; i < NR; i++) {
7674 final ResolveInfo info = result.get(i);
7675 if (info.activityInfo.splitName != null) {
7678 return new ComponentName(packageName, info.activityInfo.name);
7685 * @param resolveInfos list of resolve infos in descending priority order
7686 * @return if the list contains a resolve info with non-negative priority
7688 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
7689 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
7692 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
7693 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
7695 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
7697 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7698 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
7702 final ArrayList<ResolveInfo> result = new ArrayList<>();
7703 final ArrayList<ResolveInfo> alwaysList = new ArrayList<>();
7704 final ArrayList<ResolveInfo> undefinedList = new ArrayList<>();
7705 final ArrayList<ResolveInfo> alwaysAskList = new ArrayList<>();
7706 final ArrayList<ResolveInfo> neverList = new ArrayList<>();
7707 final ArrayList<ResolveInfo> matchAllList = new ArrayList<>();
7709 synchronized (mPackages) {
7710 final int count = candidates.size();
7711 // First, try to use linked apps. Partition the candidates into four lists:
7712 // one for the final results, one for the "do not use ever", one for "undefined status"
7713 // and finally one for "browser app type".
7714 for (int n=0; n<count; n++) {
7715 ResolveInfo info = candidates.get(n);
7716 String packageName = info.activityInfo.packageName;
7717 PackageSetting ps = mSettings.mPackages.get(packageName);
7719 // Add to the special match all list (Browser use case)
7720 if (info.handleAllWebDataURI) {
7721 matchAllList.add(info);
7724 // Try to get the status from User settings first
7725 long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7726 int status = (int)(packedStatus >> 32);
7727 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7728 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
7729 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7730 Slog.i(TAG, " + always: " + info.activityInfo.packageName
7731 + " : linkgen=" + linkGeneration);
7733 // Use link-enabled generation as preferredOrder, i.e.
7734 // prefer newly-enabled over earlier-enabled.
7735 info.preferredOrder = linkGeneration;
7736 alwaysList.add(info);
7737 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7738 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7739 Slog.i(TAG, " + never: " + info.activityInfo.packageName);
7741 neverList.add(info);
7742 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7743 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7744 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName);
7746 alwaysAskList.add(info);
7747 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7748 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7749 if (DEBUG_DOMAIN_VERIFICATION || debug) {
7750 Slog.i(TAG, " + ask: " + info.activityInfo.packageName);
7752 undefinedList.add(info);
7757 // We'll want to include browser possibilities in a few cases
7758 boolean includeBrowser = false;
7760 // First try to add the "always" resolution(s) for the current user, if any
7761 if (alwaysList.size() > 0) {
7762 result.addAll(alwaysList);
7764 // Add all undefined apps as we want them to appear in the disambiguation dialog.
7765 result.addAll(undefinedList);
7766 // Maybe add one for the other profile.
7767 if (xpDomainInfo != null && (
7768 xpDomainInfo.bestDomainVerificationStatus
7769 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7770 result.add(xpDomainInfo.resolveInfo);
7772 includeBrowser = true;
7775 // The presence of any 'always ask' alternatives means we'll also offer browsers.
7776 // If there were 'always' entries their preferred order has been set, so we also
7777 // back that off to make the alternatives equivalent
7778 if (alwaysAskList.size() > 0) {
7779 for (ResolveInfo i : result) {
7780 i.preferredOrder = 0;
7782 result.addAll(alwaysAskList);
7783 includeBrowser = true;
7786 if (includeBrowser) {
7787 // Also add browsers (all of them or only the default one)
7788 if (DEBUG_DOMAIN_VERIFICATION) {
7789 Slog.v(TAG, " ...including browsers in candidate set");
7791 if ((matchFlags & MATCH_ALL) != 0) {
7792 result.addAll(matchAllList);
7794 // Browser/generic handling case. If there's a default browser, go straight
7795 // to that (but only if there is no other higher-priority match).
7796 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
7797 int maxMatchPrio = 0;
7798 ResolveInfo defaultBrowserMatch = null;
7799 final int numCandidates = matchAllList.size();
7800 for (int n = 0; n < numCandidates; n++) {
7801 ResolveInfo info = matchAllList.get(n);
7802 // track the highest overall match priority...
7803 if (info.priority > maxMatchPrio) {
7804 maxMatchPrio = info.priority;
7806 // ...and the highest-priority default browser match
7807 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7808 if (defaultBrowserMatch == null
7809 || (defaultBrowserMatch.priority < info.priority)) {
7811 Slog.v(TAG, "Considering default browser match " + info);
7813 defaultBrowserMatch = info;
7817 if (defaultBrowserMatch != null
7818 && defaultBrowserMatch.priority >= maxMatchPrio
7819 && !TextUtils.isEmpty(defaultBrowserPackageName))
7822 Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7824 result.add(defaultBrowserMatch);
7826 result.addAll(matchAllList);
7830 // If there is nothing selected, add all candidates and remove the ones that the user
7831 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7832 if (result.size() == 0) {
7833 result.addAll(candidates);
7834 result.removeAll(neverList);
7838 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7839 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7841 for (ResolveInfo info : result) {
7842 Slog.v(TAG, " + " + info.activityInfo);
7848 // Returns a packed value as a long:
7850 // high 'int'-sized word: link status: undefined/ask/never/always.
7851 // low 'int'-sized word: relative priority among 'always' results.
7852 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7853 long result = ps.getDomainVerificationStatusForUser(userId);
7854 // if none available, get the master status
7855 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7856 if (ps.getIntentFilterVerificationInfo() != null) {
7857 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7863 private ResolveInfo querySkipCurrentProfileIntents(
7864 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7865 int flags, int sourceUserId) {
7866 if (matchingFilters != null) {
7867 int size = matchingFilters.size();
7868 for (int i = 0; i < size; i ++) {
7869 CrossProfileIntentFilter filter = matchingFilters.get(i);
7870 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7871 // Checking if there are activities in the target user that can handle the
7873 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7874 resolvedType, flags, sourceUserId);
7875 if (resolveInfo != null) {
7884 // Return matching ResolveInfo in target user if any.
7885 private ResolveInfo queryCrossProfileIntents(
7886 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7887 int flags, int sourceUserId, boolean matchInCurrentProfile) {
7888 if (matchingFilters != null) {
7889 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7890 // match the same intent. For performance reasons, it is better not to
7891 // run queryIntent twice for the same userId
7892 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7893 int size = matchingFilters.size();
7894 for (int i = 0; i < size; i++) {
7895 CrossProfileIntentFilter filter = matchingFilters.get(i);
7896 int targetUserId = filter.getTargetUserId();
7897 boolean skipCurrentProfile =
7898 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7899 boolean skipCurrentProfileIfNoMatchFound =
7900 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7901 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7902 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7903 // Checking if there are activities in the target user that can handle the
7905 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7906 resolvedType, flags, sourceUserId);
7907 if (resolveInfo != null) return resolveInfo;
7908 alreadyTriedUserIds.put(targetUserId, true);
7916 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7917 * will forward the intent to the filter's target user.
7918 * Otherwise, returns null.
7920 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7921 String resolvedType, int flags, int sourceUserId) {
7922 int targetUserId = filter.getTargetUserId();
7923 List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent,
7924 resolvedType, flags, targetUserId);
7925 if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7926 // If all the matches in the target profile are suspended, return null.
7927 for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7928 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7929 & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7930 return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7938 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7939 int sourceUserId, int targetUserId) {
7940 ResolveInfo forwardingResolveInfo = new ResolveInfo();
7941 long ident = Binder.clearCallingIdentity();
7942 boolean targetIsProfile;
7944 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7946 Binder.restoreCallingIdentity(ident);
7949 if (targetIsProfile) {
7950 className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7952 className = FORWARD_INTENT_TO_PARENT;
7954 ComponentName forwardingActivityComponentName = new ComponentName(
7955 mAndroidApplication.packageName, className);
7956 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7958 if (!targetIsProfile) {
7959 forwardingActivityInfo.showUserIcon = targetUserId;
7960 forwardingResolveInfo.noResourceId = true;
7962 forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7963 forwardingResolveInfo.priority = 0;
7964 forwardingResolveInfo.preferredOrder = 0;
7965 forwardingResolveInfo.match = 0;
7966 forwardingResolveInfo.isDefault = true;
7967 forwardingResolveInfo.filter = filter;
7968 forwardingResolveInfo.targetUserId = targetUserId;
7969 return forwardingResolveInfo;
7973 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7974 Intent[] specifics, String[] specificTypes, Intent intent,
7975 String resolvedType, int flags, int userId) {
7976 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7977 specificTypes, intent, resolvedType, flags, userId));
7980 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7981 Intent[] specifics, String[] specificTypes, Intent intent,
7982 String resolvedType, int flags, int userId) {
7983 if (!sUserManager.exists(userId)) return Collections.emptyList();
7984 final int callingUid = Binder.getCallingUid();
7985 flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7986 false /*includeInstantApps*/);
7987 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7988 false /*requireFullPermission*/, false /*checkShell*/,
7989 "query intent activity options");
7990 final String resultsAction = intent.getAction();
7992 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7993 | PackageManager.GET_RESOLVED_FILTER, userId);
7995 if (DEBUG_INTENT_MATCHING) {
7996 Log.v(TAG, "Query " + intent + ": " + results);
7999 int specificsPos = 0;
8002 // todo: note that the algorithm used here is O(N^2). This
8003 // isn't a problem in our current environment, but if we start running
8004 // into situations where we have more than 5 or 10 matches then this
8005 // should probably be changed to something smarter...
8007 // First we go through and resolve each of the specific items
8008 // that were supplied, taking care of removing any corresponding
8009 // duplicate items in the generic resolve list.
8010 if (specifics != null) {
8011 for (int i=0; i<specifics.length; i++) {
8012 final Intent sintent = specifics[i];
8013 if (sintent == null) {
8017 if (DEBUG_INTENT_MATCHING) {
8018 Log.v(TAG, "Specific #" + i + ": " + sintent);
8021 String action = sintent.getAction();
8022 if (resultsAction != null && resultsAction.equals(action)) {
8023 // If this action was explicitly requested, then don't
8024 // remove things that have it.
8028 ResolveInfo ri = null;
8029 ActivityInfo ai = null;
8031 ComponentName comp = sintent.getComponent();
8035 specificTypes != null ? specificTypes[i] : null,
8040 if (ri == mResolveInfo) {
8041 // ACK! Must do something better with this.
8043 ai = ri.activityInfo;
8044 comp = new ComponentName(ai.applicationInfo.packageName,
8047 ai = getActivityInfo(comp, flags, userId);
8053 // Look for any generic query activities that are duplicates
8054 // of this specific one, and remove them from the results.
8055 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
8058 for (j=specificsPos; j<N; j++) {
8059 ResolveInfo sri = results.get(j);
8060 if ((sri.activityInfo.name.equals(comp.getClassName())
8061 && sri.activityInfo.applicationInfo.packageName.equals(
8062 comp.getPackageName()))
8063 || (action != null && sri.filter.matchAction(action))) {
8065 if (DEBUG_INTENT_MATCHING) Log.v(
8066 TAG, "Removing duplicate item from " + j
8067 + " due to specific " + specificsPos);
8076 // Add this specific item to its proper place.
8078 ri = new ResolveInfo();
8079 ri.activityInfo = ai;
8081 results.add(specificsPos, ri);
8082 ri.specificIndex = i;
8087 // Now we go through the remaining generic results and remove any
8088 // duplicate actions that are found here.
8090 for (int i=specificsPos; i<N-1; i++) {
8091 final ResolveInfo rii = results.get(i);
8092 if (rii.filter == null) {
8096 // Iterate over all of the actions of this result's intent
8097 // filter... typically this should be just one.
8098 final Iterator<String> it = rii.filter.actionsIterator();
8102 while (it.hasNext()) {
8103 final String action = it.next();
8104 if (resultsAction != null && resultsAction.equals(action)) {
8105 // If this action was explicitly requested, then don't
8106 // remove things that have it.
8109 for (int j=i+1; j<N; j++) {
8110 final ResolveInfo rij = results.get(j);
8111 if (rij.filter != null && rij.filter.hasAction(action)) {
8113 if (DEBUG_INTENT_MATCHING) Log.v(
8114 TAG, "Removing duplicate item from " + j
8115 + " due to action " + action + " at " + i);
8122 // If the caller didn't request filter information, drop it now
8123 // so we don't have to marshall/unmarshall it.
8124 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
8129 // Filter out the caller activity if so requested.
8130 if (caller != null) {
8132 for (int i=0; i<N; i++) {
8133 ActivityInfo ainfo = results.get(i).activityInfo;
8134 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
8135 && caller.getClassName().equals(ainfo.name)) {
8142 // If the caller didn't request filter information,
8143 // drop them now so we don't have to
8144 // marshall/unmarshall it.
8145 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
8147 for (int i=0; i<N; i++) {
8148 results.get(i).filter = null;
8152 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
8157 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
8158 String resolvedType, int flags, int userId) {
8159 return new ParceledListSlice<>(
8160 queryIntentReceiversInternal(intent, resolvedType, flags, userId,
8161 false /*allowDynamicSplits*/));
8164 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
8165 String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
8166 if (!sUserManager.exists(userId)) return Collections.emptyList();
8167 final int callingUid = Binder.getCallingUid();
8168 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
8169 false /*requireFullPermission*/, false /*checkShell*/,
8170 "query intent receivers");
8171 final String instantAppPkgName = getInstantAppPackageName(callingUid);
8172 flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8173 false /*includeInstantApps*/);
8174 ComponentName comp = intent.getComponent();
8176 if (intent.getSelector() != null) {
8177 intent = intent.getSelector();
8178 comp = intent.getComponent();
8182 final List<ResolveInfo> list = new ArrayList<>(1);
8183 final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
8185 // When specifying an explicit component, we prevent the activity from being
8186 // used when either 1) the calling package is normal and the activity is within
8187 // an instant application or 2) the calling package is ephemeral and the
8188 // activity is not visible to instant applications.
8189 final boolean matchInstantApp =
8190 (flags & PackageManager.MATCH_INSTANT) != 0;
8191 final boolean matchVisibleToInstantAppOnly =
8192 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8193 final boolean matchExplicitlyVisibleOnly =
8194 (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
8195 final boolean isCallerInstantApp =
8196 instantAppPkgName != null;
8197 final boolean isTargetSameInstantApp =
8198 comp.getPackageName().equals(instantAppPkgName);
8199 final boolean isTargetInstantApp =
8200 (ai.applicationInfo.privateFlags
8201 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8202 final boolean isTargetVisibleToInstantApp =
8203 (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
8204 final boolean isTargetExplicitlyVisibleToInstantApp =
8205 isTargetVisibleToInstantApp
8206 && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
8207 final boolean isTargetHiddenFromInstantApp =
8208 !isTargetVisibleToInstantApp
8209 || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
8210 final boolean blockResolution =
8211 !isTargetSameInstantApp
8212 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8213 || (matchVisibleToInstantAppOnly && isCallerInstantApp
8214 && isTargetHiddenFromInstantApp));
8215 if (!blockResolution) {
8216 ResolveInfo ri = new ResolveInfo();
8217 ri.activityInfo = ai;
8221 return applyPostResolutionFilter(
8222 list, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
8227 synchronized (mPackages) {
8228 String pkgName = intent.getPackage();
8229 if (pkgName == null) {
8230 final List<ResolveInfo> result =
8231 mComponentResolver.queryReceivers(intent, resolvedType, flags, userId);
8232 return applyPostResolutionFilter(
8233 result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
8236 final PackageParser.Package pkg = mPackages.get(pkgName);
8238 final List<ResolveInfo> result = mComponentResolver.queryReceivers(
8239 intent, resolvedType, flags, pkg.receivers, userId);
8240 return applyPostResolutionFilter(
8241 result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
8244 return Collections.emptyList();
8249 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
8250 final int callingUid = Binder.getCallingUid();
8251 return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
8254 private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
8255 int userId, int callingUid) {
8256 if (!sUserManager.exists(userId)) return null;
8257 flags = updateFlagsForResolve(
8258 flags, userId, intent, callingUid, false /*includeInstantApps*/);
8259 List<ResolveInfo> query = queryIntentServicesInternal(
8260 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
8261 if (query != null) {
8262 if (query.size() >= 1) {
8263 // If there is more than one service with the same priority,
8264 // just arbitrarily pick the first one.
8265 return query.get(0);
8272 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
8273 String resolvedType, int flags, int userId) {
8274 final int callingUid = Binder.getCallingUid();
8275 return new ParceledListSlice<>(queryIntentServicesInternal(
8276 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
8279 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
8280 String resolvedType, int flags, int userId, int callingUid,
8281 boolean includeInstantApps) {
8282 if (!sUserManager.exists(userId)) return Collections.emptyList();
8283 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
8284 false /*requireFullPermission*/, false /*checkShell*/,
8285 "query intent receivers");
8286 final String instantAppPkgName = getInstantAppPackageName(callingUid);
8287 flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
8288 ComponentName comp = intent.getComponent();
8290 if (intent.getSelector() != null) {
8291 intent = intent.getSelector();
8292 comp = intent.getComponent();
8296 final List<ResolveInfo> list = new ArrayList<>(1);
8297 final ServiceInfo si = getServiceInfo(comp, flags, userId);
8299 // When specifying an explicit component, we prevent the service from being
8300 // used when either 1) the service is in an instant application and the
8301 // caller is not the same instant application or 2) the calling package is
8302 // ephemeral and the activity is not visible to ephemeral applications.
8303 final boolean matchInstantApp =
8304 (flags & PackageManager.MATCH_INSTANT) != 0;
8305 final boolean matchVisibleToInstantAppOnly =
8306 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8307 final boolean isCallerInstantApp =
8308 instantAppPkgName != null;
8309 final boolean isTargetSameInstantApp =
8310 comp.getPackageName().equals(instantAppPkgName);
8311 final boolean isTargetInstantApp =
8312 (si.applicationInfo.privateFlags
8313 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8314 final boolean isTargetHiddenFromInstantApp =
8315 (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8316 final boolean blockResolution =
8317 !isTargetSameInstantApp
8318 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8319 || (matchVisibleToInstantAppOnly && isCallerInstantApp
8320 && isTargetHiddenFromInstantApp));
8321 if (!blockResolution) {
8322 final ResolveInfo ri = new ResolveInfo();
8323 ri.serviceInfo = si;
8331 synchronized (mPackages) {
8332 String pkgName = intent.getPackage();
8333 if (pkgName == null) {
8334 return applyPostServiceResolutionFilter(
8335 mComponentResolver.queryServices(intent, resolvedType, flags, userId),
8338 final PackageParser.Package pkg = mPackages.get(pkgName);
8340 return applyPostServiceResolutionFilter(
8341 mComponentResolver.queryServices(intent, resolvedType, flags, pkg.services,
8345 return Collections.emptyList();
8349 private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
8350 String instantAppPkgName) {
8351 if (instantAppPkgName == null) {
8352 return resolveInfos;
8354 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8355 final ResolveInfo info = resolveInfos.get(i);
8356 final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
8357 // allow services that are defined in the provided package
8358 if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
8359 if (info.serviceInfo.splitName != null
8360 && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
8361 info.serviceInfo.splitName)) {
8362 // requested service is defined in a split that hasn't been installed yet.
8363 // add the installer to the resolve list
8364 if (DEBUG_INSTANT) {
8365 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8367 final ResolveInfo installerInfo = new ResolveInfo(
8368 mInstantAppInstallerInfo);
8369 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8370 null /* installFailureActivity */,
8371 info.serviceInfo.packageName,
8372 info.serviceInfo.applicationInfo.longVersionCode,
8373 info.serviceInfo.splitName);
8374 // add a non-generic filter
8375 installerInfo.filter = new IntentFilter();
8376 // load resources from the correct package
8377 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8378 resolveInfos.set(i, installerInfo);
8382 // allow services that have been explicitly exposed to ephemeral apps
8384 && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8387 resolveInfos.remove(i);
8389 return resolveInfos;
8393 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
8394 String resolvedType, int flags, int userId) {
8395 return new ParceledListSlice<>(
8396 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
8399 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
8400 Intent intent, String resolvedType, int flags, int userId) {
8401 if (!sUserManager.exists(userId)) return Collections.emptyList();
8402 final int callingUid = Binder.getCallingUid();
8403 final String instantAppPkgName = getInstantAppPackageName(callingUid);
8404 flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8405 false /*includeInstantApps*/);
8406 ComponentName comp = intent.getComponent();
8408 if (intent.getSelector() != null) {
8409 intent = intent.getSelector();
8410 comp = intent.getComponent();
8414 final List<ResolveInfo> list = new ArrayList<>(1);
8415 final ProviderInfo pi = getProviderInfo(comp, flags, userId);
8417 // When specifying an explicit component, we prevent the provider from being
8418 // used when either 1) the provider is in an instant application and the
8419 // caller is not the same instant application or 2) the calling package is an
8420 // instant application and the provider is not visible to instant applications.
8421 final boolean matchInstantApp =
8422 (flags & PackageManager.MATCH_INSTANT) != 0;
8423 final boolean matchVisibleToInstantAppOnly =
8424 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8425 final boolean isCallerInstantApp =
8426 instantAppPkgName != null;
8427 final boolean isTargetSameInstantApp =
8428 comp.getPackageName().equals(instantAppPkgName);
8429 final boolean isTargetInstantApp =
8430 (pi.applicationInfo.privateFlags
8431 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8432 final boolean isTargetHiddenFromInstantApp =
8433 (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8434 final boolean blockResolution =
8435 !isTargetSameInstantApp
8436 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8437 || (matchVisibleToInstantAppOnly && isCallerInstantApp
8438 && isTargetHiddenFromInstantApp));
8439 if (!blockResolution) {
8440 final ResolveInfo ri = new ResolveInfo();
8441 ri.providerInfo = pi;
8449 synchronized (mPackages) {
8450 String pkgName = intent.getPackage();
8451 if (pkgName == null) {
8452 return applyPostContentProviderResolutionFilter(
8453 mComponentResolver.queryProviders(intent, resolvedType, flags, userId),
8456 final PackageParser.Package pkg = mPackages.get(pkgName);
8458 return applyPostContentProviderResolutionFilter(
8459 mComponentResolver.queryProviders(intent, resolvedType, flags,
8460 pkg.providers, userId),
8463 return Collections.emptyList();
8467 private List<ResolveInfo> applyPostContentProviderResolutionFilter(
8468 List<ResolveInfo> resolveInfos, String instantAppPkgName) {
8469 if (instantAppPkgName == null) {
8470 return resolveInfos;
8472 for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8473 final ResolveInfo info = resolveInfos.get(i);
8474 final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
8475 // allow providers that are defined in the provided package
8476 if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
8477 if (info.providerInfo.splitName != null
8478 && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
8479 info.providerInfo.splitName)) {
8480 // requested provider is defined in a split that hasn't been installed yet.
8481 // add the installer to the resolve list
8482 if (DEBUG_INSTANT) {
8483 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8485 final ResolveInfo installerInfo = new ResolveInfo(
8486 mInstantAppInstallerInfo);
8487 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8488 null /*failureActivity*/,
8489 info.providerInfo.packageName,
8490 info.providerInfo.applicationInfo.longVersionCode,
8491 info.providerInfo.splitName);
8492 // add a non-generic filter
8493 installerInfo.filter = new IntentFilter();
8494 // load resources from the correct package
8495 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8496 resolveInfos.set(i, installerInfo);
8500 // allow providers that have been explicitly exposed to instant applications
8502 && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8505 resolveInfos.remove(i);
8507 return resolveInfos;
8511 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
8512 final int callingUid = Binder.getCallingUid();
8513 if (getInstantAppPackageName(callingUid) != null) {
8514 return ParceledListSlice.emptyList();
8516 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8517 flags = updateFlagsForPackage(flags, userId, null);
8518 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8519 final boolean listApex = (flags & MATCH_APEX) != 0;
8520 final boolean listFactory = (flags & MATCH_FACTORY_ONLY) != 0;
8522 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
8523 false /* requireFullPermission */, false /* checkShell */,
8524 "get installed packages");
8527 synchronized (mPackages) {
8528 ArrayList<PackageInfo> list;
8529 if (listUninstalled) {
8530 list = new ArrayList<>(mSettings.mPackages.size());
8531 for (PackageSetting ps : mSettings.mPackages.values()) {
8532 if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8535 if (filterAppAccessLPr(ps, callingUid, userId)) {
8538 final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8544 list = new ArrayList<>(mPackages.size());
8545 for (PackageParser.Package p : mPackages.values()) {
8546 final PackageSetting ps = (PackageSetting) p.mExtras;
8547 if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8550 if (filterAppAccessLPr(ps, callingUid, userId)) {
8553 final PackageInfo pi = generatePackageInfo((PackageSetting)
8554 p.mExtras, flags, userId);
8562 list.addAll(mApexManager.getFactoryPackages());
8564 list.addAll(mApexManager.getActivePackages());
8566 if (listUninstalled) {
8567 list.addAll(mApexManager.getInactivePackages());
8570 return new ParceledListSlice<>(list);
8574 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
8575 String[] permissions, boolean[] tmp, int flags, int userId) {
8577 final PermissionsState permissionsState = ps.getPermissionsState();
8578 for (int i=0; i<permissions.length; i++) {
8579 final String permission = permissions[i];
8580 if (permissionsState.hasPermission(permission, userId)) {
8587 if (numMatch == 0) {
8590 final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8592 // The above might return null in cases of uninstalled apps or install-state
8593 // skew across users/profiles.
8595 if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
8596 if (numMatch == permissions.length) {
8597 pi.requestedPermissions = permissions;
8599 pi.requestedPermissions = new String[numMatch];
8601 for (int i=0; i<permissions.length; i++) {
8603 pi.requestedPermissions[numMatch] = permissions[i];
8614 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
8615 String[] permissions, int flags, int userId) {
8616 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8617 flags = updateFlagsForPackage(flags, userId, permissions);
8618 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8619 true /* requireFullPermission */, false /* checkShell */,
8620 "get packages holding permissions");
8621 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8624 synchronized (mPackages) {
8625 ArrayList<PackageInfo> list = new ArrayList<>();
8626 boolean[] tmpBools = new boolean[permissions.length];
8627 if (listUninstalled) {
8628 for (PackageSetting ps : mSettings.mPackages.values()) {
8629 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8633 for (PackageParser.Package pkg : mPackages.values()) {
8634 PackageSetting ps = (PackageSetting)pkg.mExtras;
8636 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8642 return new ParceledListSlice<>(list);
8647 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
8648 final int callingUid = Binder.getCallingUid();
8649 return new ParceledListSlice<>(
8650 getInstalledApplicationsListInternal(flags, userId, callingUid));
8653 private List<ApplicationInfo> getInstalledApplicationsListInternal(int flags, int userId,
8655 if (getInstantAppPackageName(callingUid) != null) {
8656 return Collections.emptyList();
8658 if (!sUserManager.exists(userId)) return Collections.emptyList();
8659 flags = updateFlagsForApplication(flags, userId, null);
8660 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8662 mPermissionManager.enforceCrossUserPermission(
8665 false /* requireFullPermission */,
8666 false /* checkShell */,
8667 "get installed application info");
8670 synchronized (mPackages) {
8671 ArrayList<ApplicationInfo> list;
8672 if (listUninstalled) {
8673 list = new ArrayList<>(mSettings.mPackages.size());
8674 for (PackageSetting ps : mSettings.mPackages.values()) {
8676 int effectiveFlags = flags;
8677 if (ps.isSystem()) {
8678 effectiveFlags |= PackageManager.MATCH_ANY_USER;
8680 if (ps.pkg != null) {
8681 if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8684 if (filterAppAccessLPr(ps, callingUid, userId)) {
8687 ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
8688 ps.readUserState(userId), userId);
8690 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
8693 // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
8694 // and already converts to externally visible package name
8695 ai = generateApplicationInfoFromSettingsLPw(ps.name,
8696 callingUid, effectiveFlags, userId);
8703 list = new ArrayList<>(mPackages.size());
8704 for (PackageParser.Package p : mPackages.values()) {
8705 if (p.mExtras != null) {
8706 PackageSetting ps = (PackageSetting) p.mExtras;
8707 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
8710 if (filterAppAccessLPr(ps, callingUid, userId)) {
8713 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8714 ps.readUserState(userId), userId);
8716 ai.packageName = resolveExternalPackageNameLPr(p);
8728 public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
8729 if (HIDE_EPHEMERAL_APIS) {
8732 if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8733 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8734 "getEphemeralApplications");
8736 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8737 true /* requireFullPermission */, false /* checkShell */,
8738 "getEphemeralApplications");
8739 synchronized (mPackages) {
8740 List<InstantAppInfo> instantApps = mInstantAppRegistry
8741 .getInstantAppsLPr(userId);
8742 if (instantApps != null) {
8743 return new ParceledListSlice<>(instantApps);
8750 public boolean isInstantApp(String packageName, int userId) {
8751 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8752 true /* requireFullPermission */, false /* checkShell */,
8754 if (HIDE_EPHEMERAL_APIS) {
8758 synchronized (mPackages) {
8759 int callingUid = Binder.getCallingUid();
8760 if (Process.isIsolated(callingUid)) {
8761 callingUid = mIsolatedOwners.get(callingUid);
8763 final PackageSetting ps = mSettings.mPackages.get(packageName);
8764 PackageParser.Package pkg = mPackages.get(packageName);
8765 final boolean returnAllowed =
8767 && (isCallerSameApp(packageName, callingUid)
8768 || canViewInstantApps(callingUid, userId)
8769 || mInstantAppRegistry.isInstantAccessGranted(
8770 userId, UserHandle.getAppId(callingUid), ps.appId));
8771 if (returnAllowed) {
8772 return ps.getInstantApp(userId);
8779 public byte[] getInstantAppCookie(String packageName, int userId) {
8780 if (HIDE_EPHEMERAL_APIS) {
8784 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8785 true /* requireFullPermission */, false /* checkShell */,
8786 "getInstantAppCookie");
8787 if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8790 synchronized (mPackages) {
8791 return mInstantAppRegistry.getInstantAppCookieLPw(
8792 packageName, userId);
8797 public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8798 if (HIDE_EPHEMERAL_APIS) {
8802 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8803 true /* requireFullPermission */, true /* checkShell */,
8804 "setInstantAppCookie");
8805 if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8808 synchronized (mPackages) {
8809 return mInstantAppRegistry.setInstantAppCookieLPw(
8810 packageName, cookie, userId);
8815 public Bitmap getInstantAppIcon(String packageName, int userId) {
8816 if (HIDE_EPHEMERAL_APIS) {
8820 if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8821 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8822 "getInstantAppIcon");
8824 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8825 true /* requireFullPermission */, false /* checkShell */,
8826 "getInstantAppIcon");
8828 synchronized (mPackages) {
8829 return mInstantAppRegistry.getInstantAppIconLPw(
8830 packageName, userId);
8834 private boolean isCallerSameApp(String packageName, int uid) {
8835 PackageParser.Package pkg = mPackages.get(packageName);
8837 && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
8841 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8842 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8843 return ParceledListSlice.emptyList();
8845 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8848 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8849 final ArrayList<ApplicationInfo> finalList = new ArrayList<>();
8852 synchronized (mPackages) {
8853 final Iterator<PackageParser.Package> i = mPackages.values().iterator();
8854 final int userId = UserHandle.getCallingUserId();
8855 while (i.hasNext()) {
8856 final PackageParser.Package p = i.next();
8857 if (p.applicationInfo == null) continue;
8859 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8860 && !p.applicationInfo.isDirectBootAware();
8861 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8862 && p.applicationInfo.isDirectBootAware();
8864 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
8865 && (!mSafeMode || isSystemApp(p))
8866 && (matchesUnaware || matchesAware)) {
8867 PackageSetting ps = mSettings.mPackages.get(p.packageName);
8869 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8870 ps.readUserState(userId), userId);
8883 public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8884 return resolveContentProviderInternal(name, flags, userId);
8887 private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
8888 if (!sUserManager.exists(userId)) return null;
8889 flags = updateFlagsForComponent(flags, userId, name);
8890 final int callingUid = Binder.getCallingUid();
8891 final ProviderInfo providerInfo = mComponentResolver.queryProvider(name, flags, userId);
8892 if (providerInfo == null) {
8895 if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
8898 synchronized (mPackages) {
8899 final PackageSetting ps = mSettings.mPackages.get(providerInfo.packageName);
8900 final ComponentName component =
8901 new ComponentName(providerInfo.packageName, providerInfo.name);
8902 if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8905 return providerInfo;
8913 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8914 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8917 mComponentResolver.querySyncProviders(
8918 outNames, outInfo, mSafeMode, UserHandle.getCallingUserId());
8922 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8923 int uid, int flags, String metaDataKey) {
8924 final int callingUid = Binder.getCallingUid();
8925 final int userId = processName != null ? UserHandle.getUserId(uid)
8926 : UserHandle.getCallingUserId();
8927 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8928 flags = updateFlagsForComponent(flags, userId, processName);
8929 ArrayList<ProviderInfo> finalList = null;
8930 final List<ProviderInfo> matchList =
8931 mComponentResolver.queryProviders(processName, metaDataKey, uid, flags, userId);
8932 final int listSize = (matchList == null ? 0 : matchList.size());
8933 synchronized (mPackages) {
8934 for (int i = 0; i < listSize; i++) {
8935 final ProviderInfo providerInfo = matchList.get(i);
8936 if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
8939 final PackageSetting ps = mSettings.mPackages.get(providerInfo.packageName);
8940 final ComponentName component =
8941 new ComponentName(providerInfo.packageName, providerInfo.name);
8942 if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8945 if (finalList == null) {
8946 finalList = new ArrayList<>(listSize - i);
8948 finalList.add(providerInfo);
8952 if (finalList != null) {
8953 finalList.sort(sProviderInitOrderSorter);
8954 return new ParceledListSlice<>(finalList);
8957 return ParceledListSlice.emptyList();
8961 public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8963 synchronized (mPackages) {
8964 final int callingUid = Binder.getCallingUid();
8965 final int callingUserId = UserHandle.getUserId(callingUid);
8966 final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
8967 if (ps == null) return null;
8968 if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8971 final PackageParser.Instrumentation i = mInstrumentation.get(component);
8972 return PackageParser.generateInstrumentationInfo(i, flags);
8977 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8978 String targetPackage, int flags) {
8979 final int callingUid = Binder.getCallingUid();
8980 final int callingUserId = UserHandle.getUserId(callingUid);
8981 final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8982 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
8983 return ParceledListSlice.emptyList();
8985 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8988 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8990 ArrayList<InstrumentationInfo> finalList = new ArrayList<>();
8993 synchronized (mPackages) {
8994 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8995 while (i.hasNext()) {
8996 final PackageParser.Instrumentation p = i.next();
8997 if (targetPackage == null
8998 || targetPackage.equals(p.info.targetPackage)) {
8999 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
9011 private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags, long currentTime) {
9012 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
9014 scanDirLI(scanDir, parseFlags, scanFlags, currentTime);
9016 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9020 private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime) {
9021 final File[] files = scanDir.listFiles();
9022 if (ArrayUtils.isEmpty(files)) {
9023 Log.d(TAG, "No files in app dir " + scanDir);
9027 if (DEBUG_PACKAGE_SCANNING) {
9028 Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
9029 + " flags=0x" + Integer.toHexString(parseFlags));
9031 try (ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
9032 mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
9033 mParallelPackageParserCallback)) {
9034 // Submit files for parsing in parallel
9036 for (File file : files) {
9037 final boolean isPackage = (isApkFile(file) || file.isDirectory())
9038 && !PackageInstallerService.isStageName(file.getName());
9040 // Ignore entries which are not packages
9043 parallelPackageParser.submit(file, parseFlags);
9047 // Process results one by one
9048 for (; fileCount > 0; fileCount--) {
9049 ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
9050 Throwable throwable = parseResult.throwable;
9051 int errorCode = PackageManager.INSTALL_SUCCEEDED;
9053 if (throwable == null) {
9054 // TODO(toddke): move lower in the scan chain
9055 // Static shared libraries have synthetic package names
9056 if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
9057 renameStaticSharedLibraryPackage(parseResult.pkg);
9060 scanPackageChildLI(parseResult.pkg, parseFlags, scanFlags,
9062 } catch (PackageManagerException e) {
9063 errorCode = e.error;
9064 Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
9066 } else if (throwable instanceof PackageParser.PackageParserException) {
9067 PackageParser.PackageParserException e = (PackageParser.PackageParserException)
9069 errorCode = e.error;
9070 Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
9072 throw new IllegalStateException("Unexpected exception occurred while parsing "
9073 + parseResult.scanFile, throwable);
9076 // Delete invalid userdata apps
9077 if ((scanFlags & SCAN_AS_SYSTEM) == 0 &&
9078 errorCode != PackageManager.INSTALL_SUCCEEDED) {
9079 logCriticalInfo(Log.WARN,
9080 "Deleting invalid package at " + parseResult.scanFile);
9081 removeCodePathLI(parseResult.scanFile);
9087 public static void reportSettingsProblem(int priority, String msg) {
9088 logCriticalInfo(priority, msg);
9091 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg,
9092 boolean forceCollect, boolean skipVerify) throws PackageManagerException {
9093 // When upgrading from pre-N MR1, verify the package time stamp using the package
9094 // directory and not the APK file.
9095 final long lastModifiedTime = mIsPreNMR1Upgrade
9096 ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg);
9097 final VersionInfo settingsVersionForPackage = getSettingsVersionForPackage(pkg);
9098 if (ps != null && !forceCollect
9099 && ps.codePathString.equals(pkg.codePath)
9100 && ps.timeStamp == lastModifiedTime
9101 && !isCompatSignatureUpdateNeeded(settingsVersionForPackage)
9102 && !isRecoverSignatureUpdateNeeded(settingsVersionForPackage)) {
9103 if (ps.signatures.mSigningDetails.signatures != null
9104 && ps.signatures.mSigningDetails.signatures.length != 0
9105 && ps.signatures.mSigningDetails.signatureSchemeVersion
9106 != SignatureSchemeVersion.UNKNOWN) {
9107 // Optimization: reuse the existing cached signing data
9108 // if the package appears to be unchanged.
9109 pkg.mSigningDetails =
9110 new PackageParser.SigningDetails(ps.signatures.mSigningDetails);
9114 Slog.w(TAG, "PackageSetting for " + ps.name
9115 + " is missing signatures. Collecting certs again to recover them.");
9117 Slog.i(TAG, pkg.codePath + " changed; collecting certs" +
9118 (forceCollect ? " (forced)" : ""));
9122 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
9123 PackageParser.collectCertificates(pkg, skipVerify);
9124 } catch (PackageParserException e) {
9125 throw PackageManagerException.from(e);
9127 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9132 * Clear the package profile if this was an upgrade and the package
9133 * version was updated.
9135 private void maybeClearProfilesForUpgradesLI(
9136 @Nullable PackageSetting originalPkgSetting,
9137 @NonNull PackageParser.Package currentPkg) {
9138 if (originalPkgSetting == null || !isDeviceUpgrading()) {
9141 if (originalPkgSetting.versionCode == currentPkg.mVersionCode) {
9145 clearAppProfilesLIF(currentPkg, UserHandle.USER_ALL);
9146 if (DEBUG_INSTALL) {
9147 Slog.d(TAG, originalPkgSetting.name
9148 + " clear profile due to version change "
9149 + originalPkgSetting.versionCode + " != "
9150 + currentPkg.mVersionCode);
9155 * Traces a package scan.
9156 * @see #scanPackageLI(File, int, int, long, UserHandle)
9158 @GuardedBy({"mInstallLock", "mPackages"})
9159 private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
9160 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
9161 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
9163 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
9165 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9170 * Scans a package and returns the newly parsed package.
9171 * Returns {@code null} in case of errors and the error code is stored in mLastScanError
9173 @GuardedBy({"mInstallLock", "mPackages"})
9174 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
9175 long currentTime, UserHandle user) throws PackageManagerException {
9176 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
9177 PackageParser pp = new PackageParser();
9178 pp.setSeparateProcesses(mSeparateProcesses);
9179 pp.setOnlyCoreApps(mOnlyCore);
9180 pp.setDisplayMetrics(mMetrics);
9181 pp.setCallback(mPackageParserCallback);
9183 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
9184 final PackageParser.Package pkg;
9186 pkg = pp.parsePackage(scanFile, parseFlags);
9187 } catch (PackageParserException e) {
9188 throw PackageManagerException.from(e);
9190 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9193 // Static shared libraries have synthetic package names
9194 if (pkg.applicationInfo.isStaticSharedLibrary()) {
9195 renameStaticSharedLibraryPackage(pkg);
9198 return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
9202 * Scans a package and returns the newly parsed package.
9203 * @throws PackageManagerException on a parse error.
9205 @GuardedBy({"mInstallLock", "mPackages"})
9206 private PackageParser.Package scanPackageChildLI(PackageParser.Package pkg,
9207 final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
9208 @Nullable UserHandle user)
9209 throws PackageManagerException {
9210 // If the package has children and this is the first dive in the function
9211 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
9212 // packages (parent and children) would be successfully scanned before the
9213 // actual scan since scanning mutates internal state and we want to atomically
9214 // install the package and its children.
9215 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9216 if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9217 scanFlags |= SCAN_CHECK_ONLY;
9220 scanFlags &= ~SCAN_CHECK_ONLY;
9224 PackageParser.Package scannedPkg = addForInitLI(pkg, parseFlags,
9225 scanFlags, currentTime, user);
9227 // Scan the children
9228 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9229 for (int i = 0; i < childCount; i++) {
9230 PackageParser.Package childPackage = pkg.childPackages.get(i);
9231 addForInitLI(childPackage, parseFlags, scanFlags,
9236 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9237 return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
9244 * Returns if forced apk verification can be skipped for the whole package, including splits.
9246 private boolean canSkipForcedPackageVerification(PackageParser.Package pkg) {
9247 if (!canSkipForcedApkVerification(pkg.baseCodePath)) {
9250 // TODO: Allow base and splits to be verified individually.
9251 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
9252 for (int i = 0; i < pkg.splitCodePaths.length; i++) {
9253 if (!canSkipForcedApkVerification(pkg.splitCodePaths[i])) {
9262 * Returns if forced apk verification can be skipped, depending on current FSVerity setup and
9263 * whether the apk contains signed root hash. Note that the signer's certificate still needs to
9264 * match one in a trusted source, and should be done separately.
9266 private boolean canSkipForcedApkVerification(String apkPath) {
9267 if (!PackageManagerServiceUtils.isLegacyApkVerityEnabled()) {
9268 return VerityUtils.hasFsverity(apkPath);
9272 final byte[] rootHashObserved = VerityUtils.generateApkVerityRootHash(apkPath);
9273 if (rootHashObserved == null) {
9274 return false; // APK does not contain Merkle tree root hash.
9276 synchronized (mInstallLock) {
9277 // Returns whether the observed root hash matches what kernel has.
9278 mInstaller.assertFsverityRootHashMatches(apkPath, rootHashObserved);
9281 } catch (InstallerException | IOException | DigestException |
9282 NoSuchAlgorithmException e) {
9283 Slog.w(TAG, "Error in fsverity check. Fallback to full apk verification.", e);
9289 * Adds a new package to the internal data structures during platform initialization.
9290 * <p>After adding, the package is known to the system and available for querying.
9291 * <p>For packages located on the device ROM [eg. packages located in /system, /vendor,
9292 * etc...], additional checks are performed. Basic verification [such as ensuring
9293 * matching signatures, checking version codes, etc...] occurs if the package is
9294 * identical to a previously known package. If the package fails a signature check,
9295 * the version installed on /data will be removed. If the version of the new package
9296 * is less than or equal than the version on /data, it will be ignored.
9297 * <p>Regardless of the package location, the results are applied to the internal
9298 * structures and the package is made available to the rest of the system.
9299 * <p>NOTE: The return value should be removed. It's the passed in package object.
9301 @GuardedBy({"mInstallLock", "mPackages"})
9302 private PackageParser.Package addForInitLI(PackageParser.Package pkg,
9303 @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
9304 @Nullable UserHandle user)
9305 throws PackageManagerException {
9306 final boolean scanSystemPartition = (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0;
9307 final String renamedPkgName;
9308 final PackageSetting disabledPkgSetting;
9309 final boolean isSystemPkgUpdated;
9310 final boolean pkgAlreadyExists;
9311 PackageSetting pkgSetting;
9313 // NOTE: installPackageLI() has the same code to setup the package's
9314 // application info. This probably should be done lower in the call
9315 // stack [such as scanPackageOnly()]. However, we verify the application
9316 // info prior to that [in scanPackageNew()] and thus have to setup
9317 // the application info early.
9318 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
9319 pkg.setApplicationInfoCodePath(pkg.codePath);
9320 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
9321 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
9322 pkg.setApplicationInfoResourcePath(pkg.codePath);
9323 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
9324 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
9326 synchronized (mPackages) {
9327 renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
9328 final String realPkgName = getRealPackageName(pkg, renamedPkgName);
9329 if (realPkgName != null) {
9330 ensurePackageRenamed(pkg, renamedPkgName);
9332 final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
9333 final PackageSetting installedPkgSetting = mSettings.getPackageLPr(pkg.packageName);
9334 pkgSetting = originalPkgSetting == null ? installedPkgSetting : originalPkgSetting;
9335 pkgAlreadyExists = pkgSetting != null;
9336 final String disabledPkgName = pkgAlreadyExists ? pkgSetting.name : pkg.packageName;
9337 disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(disabledPkgName);
9338 isSystemPkgUpdated = disabledPkgSetting != null;
9340 if (DEBUG_INSTALL && isSystemPkgUpdated) {
9341 Slog.d(TAG, "updatedPkg = " + disabledPkgSetting);
9344 final SharedUserSetting sharedUserSetting = (pkg.mSharedUserId != null)
9345 ? mSettings.getSharedUserLPw(pkg.mSharedUserId,
9346 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true)
9348 if (DEBUG_PACKAGE_SCANNING
9349 && (parseFlags & PackageParser.PARSE_CHATTY) != 0
9350 && sharedUserSetting != null) {
9351 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
9352 + " (uid=" + sharedUserSetting.userId + "):"
9353 + " packages=" + sharedUserSetting.packages);
9356 if (scanSystemPartition) {
9357 // Potentially prune child packages. If the application on the /system
9358 // partition has been updated via OTA, but, is still disabled by a
9359 // version on /data, cycle through all of its children packages and
9360 // remove children that are no longer defined.
9361 if (isSystemPkgUpdated) {
9362 final int scannedChildCount = (pkg.childPackages != null)
9363 ? pkg.childPackages.size() : 0;
9364 final int disabledChildCount = disabledPkgSetting.childPackageNames != null
9365 ? disabledPkgSetting.childPackageNames.size() : 0;
9366 for (int i = 0; i < disabledChildCount; i++) {
9367 String disabledChildPackageName =
9368 disabledPkgSetting.childPackageNames.get(i);
9369 boolean disabledPackageAvailable = false;
9370 for (int j = 0; j < scannedChildCount; j++) {
9371 PackageParser.Package childPkg = pkg.childPackages.get(j);
9372 if (childPkg.packageName.equals(disabledChildPackageName)) {
9373 disabledPackageAvailable = true;
9377 if (!disabledPackageAvailable) {
9378 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
9381 // we're updating the disabled package, so, scan it as the package setting
9382 final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, null,
9383 disabledPkgSetting /* pkgSetting */, null /* disabledPkgSetting */,
9384 null /* originalPkgSetting */, null, parseFlags, scanFlags,
9385 (pkg == mPlatformPackage), user);
9386 applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage);
9387 final ScanResult scanResult = scanPackageOnlyLI(request, mFactoryTest, -1L);
9388 if (scanResult.existingSettingCopied && scanResult.request.pkgSetting != null) {
9389 scanResult.request.pkgSetting.updateFrom(scanResult.pkgSetting);
9395 final boolean newPkgChangedPaths =
9396 pkgAlreadyExists && !pkgSetting.codePathString.equals(pkg.codePath);
9397 final boolean newPkgVersionGreater =
9398 pkgAlreadyExists && pkg.getLongVersionCode() > pkgSetting.versionCode;
9399 final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
9400 && newPkgChangedPaths && newPkgVersionGreater;
9401 if (isSystemPkgBetter) {
9402 // The version of the application on /system is greater than the version on
9403 // /data. Switch back to the application on /system.
9404 // It's safe to assume the application on /system will correctly scan. If not,
9405 // there won't be a working copy of the application.
9406 synchronized (mPackages) {
9407 // just remove the loaded entries from package lists
9408 mPackages.remove(pkgSetting.name);
9411 logCriticalInfo(Log.WARN,
9412 "System package updated;"
9413 + " name: " + pkgSetting.name
9414 + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
9415 + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
9417 final InstallArgs args = createInstallArgsForExisting(
9418 pkgSetting.codePathString,
9419 pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
9420 args.cleanUpResourcesLI();
9421 synchronized (mPackages) {
9422 mSettings.enableSystemPackageLPw(pkgSetting.name);
9426 if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {
9427 // The version of the application on the /system partition is less than or
9428 // equal to the version on the /data partition. Throw an exception and use
9429 // the application already installed on the /data partition.
9430 throw new PackageManagerException(Log.WARN, "Package " + pkg.packageName + " at "
9431 + pkg.codePath + " ignored: updated version " + pkgSetting.versionCode
9432 + " better than this " + pkg.getLongVersionCode());
9435 // Verify certificates against what was last scanned. If there was an upgrade and this is an
9436 // app in a system partition, or if this is an updated priv app, we will force re-collecting
9438 final boolean forceCollect = (mIsUpgrade && scanSystemPartition)
9439 || PackageManagerServiceUtils.isApkVerificationForced(disabledPkgSetting);
9440 // Full APK verification can be skipped during certificate collection, only if the file is
9441 // in verified partition, or can be verified on access (when apk verity is enabled). In both
9442 // cases, only data in Signing Block is verified instead of the whole file.
9443 final boolean skipVerify = scanSystemPartition
9444 || (forceCollect && canSkipForcedPackageVerification(pkg));
9445 collectCertificatesLI(pkgSetting, pkg, forceCollect, skipVerify);
9447 // Reset profile if the application version is changed
9448 maybeClearProfilesForUpgradesLI(pkgSetting, pkg);
9451 * A new system app appeared, but we already had a non-system one of the
9452 * same name installed earlier.
9454 boolean shouldHideSystemApp = false;
9455 // A new application appeared on /system, but, we already have a copy of
9456 // the application installed on /data.
9457 if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists
9458 && !pkgSetting.isSystem()) {
9460 if (!pkg.mSigningDetails.checkCapability(pkgSetting.signatures.mSigningDetails,
9461 PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)
9462 && !pkgSetting.signatures.mSigningDetails.checkCapability(
9463 pkg.mSigningDetails,
9464 PackageParser.SigningDetails.CertCapabilities.ROLLBACK)) {
9465 logCriticalInfo(Log.WARN,
9466 "System package signature mismatch;"
9467 + " name: " + pkgSetting.name);
9468 try (PackageFreezer freezer = freezePackage(pkg.packageName,
9469 "scanPackageInternalLI")) {
9470 deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
9473 } else if (newPkgVersionGreater) {
9474 // The application on /system is newer than the application on /data.
9475 // Simply remove the application on /data [keeping application data]
9476 // and replace it with the version on /system.
9477 logCriticalInfo(Log.WARN,
9478 "System package enabled;"
9479 + " name: " + pkgSetting.name
9480 + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
9481 + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
9482 InstallArgs args = createInstallArgsForExisting(
9483 pkgSetting.codePathString,
9484 pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
9485 synchronized (mInstallLock) {
9486 args.cleanUpResourcesLI();
9489 // The application on /system is older than the application on /data. Hide
9490 // the application on /system and the version on /data will be scanned later
9491 // and re-added like an update.
9492 shouldHideSystemApp = true;
9493 logCriticalInfo(Log.INFO,
9494 "System package disabled;"
9495 + " name: " + pkgSetting.name
9496 + "; old: " + pkgSetting.codePathString + " @ " + pkgSetting.versionCode
9497 + "; new: " + pkg.codePath + " @ " + pkg.codePath);
9501 final ScanResult scanResult = scanPackageNewLI(pkg, parseFlags, scanFlags
9502 | SCAN_UPDATE_SIGNATURE, currentTime, user);
9503 if (scanResult.success) {
9504 synchronized (mPackages) {
9505 boolean appIdCreated = false;
9507 final String pkgName = scanResult.pkgSetting.name;
9508 final Map<String, ReconciledPackage> reconcileResult = reconcilePackagesLocked(
9509 new ReconcileRequest(
9510 Collections.singletonMap(pkgName, scanResult),
9513 Collections.singletonMap(
9514 pkgName, getSettingsVersionForPackage(pkg)),
9515 Collections.singletonMap(pkgName,
9516 getSharedLibLatestVersionSetting(scanResult))),
9517 mSettings.mKeySetManagerService);
9518 appIdCreated = optimisticallyRegisterAppId(scanResult);
9519 commitReconciledScanResultLocked(reconcileResult.get(pkgName));
9520 } catch (PackageManagerException e) {
9522 cleanUpAppIdCreation(scanResult);
9529 if (shouldHideSystemApp) {
9530 synchronized (mPackages) {
9531 mSettings.disableSystemPackageLPw(pkg.packageName, true);
9534 return scanResult.pkgSetting.pkg;
9537 private static void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
9538 // Derive the new package synthetic package name
9539 pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
9540 + pkg.staticSharedLibVersion);
9543 static String fixProcessName(String defProcessName, String processName) {
9544 if (processName == null) {
9545 return defProcessName;
9551 * Enforces that only the system UID or root's UID can call a method exposed
9554 * @param message used as message if SecurityException is thrown
9555 * @throws SecurityException if the caller is not system or root
9557 private static void enforceSystemOrRoot(String message) {
9558 final int uid = Binder.getCallingUid();
9559 if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
9560 throw new SecurityException(message);
9565 * Enforces that only the system UID or root's UID or shell's UID can call
9566 * a method exposed via Binder.
9568 * @param message used as message if SecurityException is thrown
9569 * @throws SecurityException if the caller is not system or shell
9571 private static void enforceSystemOrRootOrShell(String message) {
9572 final int uid = Binder.getCallingUid();
9573 if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID && uid != Process.SHELL_UID) {
9574 throw new SecurityException(message);
9579 public void performFstrimIfNeeded() {
9580 enforceSystemOrRoot("Only the system can request fstrim");
9582 // Before everything else, see whether we need to fstrim.
9584 IStorageManager sm = PackageHelper.getStorageManager();
9586 boolean doTrim = false;
9587 final long interval = android.provider.Settings.Global.getLong(
9588 mContext.getContentResolver(),
9589 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
9590 DEFAULT_MANDATORY_FSTRIM_INTERVAL);
9592 final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
9593 if (timeSinceLast > interval) {
9595 Slog.w(TAG, "No disk maintenance in " + timeSinceLast
9596 + "; running immediately");
9600 final boolean dexOptDialogShown;
9601 synchronized (mPackages) {
9602 dexOptDialogShown = mDexOptDialogShown;
9604 if (!isFirstBoot() && dexOptDialogShown) {
9606 ActivityManager.getService().showBootMessage(
9607 mContext.getResources().getString(
9608 R.string.android_upgrading_fstrim), true);
9609 } catch (RemoteException e) {
9612 sm.runMaintenance();
9615 Slog.e(TAG, "storageManager service unavailable!");
9617 } catch (RemoteException e) {
9618 // Can't happen; StorageManagerService is local
9623 public void updatePackagesIfNeeded() {
9624 enforceSystemOrRoot("Only the system can request package update");
9626 // We need to re-extract after an OTA.
9627 boolean causeUpgrade = isDeviceUpgrading();
9629 // First boot or factory reset.
9630 // Note: we also handle devices that are upgrading to N right now as if it is their
9631 // first boot, as they do not have profile data.
9632 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
9634 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
9635 boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
9637 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
9641 List<PackageParser.Package> pkgs;
9642 synchronized (mPackages) {
9643 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
9646 final long startTime = System.nanoTime();
9647 final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
9648 causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
9649 false /* bootComplete */);
9651 final int elapsedTimeSeconds =
9652 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
9654 MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
9655 MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
9656 MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
9657 MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
9658 MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
9662 * Return the prebuilt profile path given a package base code path.
9664 private static String getPrebuildProfilePath(PackageParser.Package pkg) {
9665 return pkg.baseCodePath + ".prof";
9669 * Performs dexopt on the set of packages in {@code packages} and returns an int array
9670 * containing statistics about the invocation. The array consists of three elements,
9671 * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
9672 * and {@code numberOfPackagesFailed}.
9674 private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
9675 final int compilationReason, boolean bootComplete) {
9677 int numberOfPackagesVisited = 0;
9678 int numberOfPackagesOptimized = 0;
9679 int numberOfPackagesSkipped = 0;
9680 int numberOfPackagesFailed = 0;
9681 final int numberOfPackagesToDexopt = pkgs.size();
9683 for (PackageParser.Package pkg : pkgs) {
9684 numberOfPackagesVisited++;
9686 boolean useProfileForDexopt = false;
9688 if ((isFirstBoot() || isDeviceUpgrading()) && isSystemApp(pkg)) {
9689 // Copy over initial preopt profiles since we won't get any JIT samples for methods
9690 // that are already compiled.
9691 File profileFile = new File(getPrebuildProfilePath(pkg));
9692 // Copy profile if it exists.
9693 if (profileFile.exists()) {
9695 // We could also do this lazily before calling dexopt in
9696 // PackageDexOptimizer to prevent this happening on first boot. The issue
9697 // is that we don't have a good way to say "do this only once".
9698 if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9699 pkg.applicationInfo.uid, pkg.packageName,
9700 ArtManager.getProfileName(null))) {
9701 Log.e(TAG, "Installer failed to copy system profile!");
9703 // Disabled as this causes speed-profile compilation during first boot
9704 // even if things are already compiled.
9705 // useProfileForDexopt = true;
9707 } catch (Exception e) {
9708 Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
9712 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9713 // Handle compressed APKs in this path. Only do this for stubs with profiles to
9714 // minimize the number off apps being speed-profile compiled during first boot.
9715 // The other paths will not change the filter.
9716 if (disabledPs != null && disabledPs.pkg.isStub) {
9717 // The package is the stub one, remove the stub suffix to get the normal
9718 // package and APK names.
9719 String systemProfilePath =
9720 getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
9721 profileFile = new File(systemProfilePath);
9722 // If we have a profile for a compressed APK, copy it to the reference
9724 // Note that copying the profile here will cause it to override the
9725 // reference profile every OTA even though the existing reference profile
9726 // may have more data. We can't copy during decompression since the
9727 // directories are not set up at that point.
9728 if (profileFile.exists()) {
9730 // We could also do this lazily before calling dexopt in
9731 // PackageDexOptimizer to prevent this happening on first boot. The
9732 // issue is that we don't have a good way to say "do this only
9734 if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9735 pkg.applicationInfo.uid, pkg.packageName,
9736 ArtManager.getProfileName(null))) {
9737 Log.e(TAG, "Failed to copy system profile for stub package!");
9739 useProfileForDexopt = true;
9741 } catch (Exception e) {
9742 Log.e(TAG, "Failed to copy profile " +
9743 profileFile.getAbsolutePath() + " ", e);
9750 if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
9752 Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
9754 numberOfPackagesSkipped++;
9759 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
9760 numberOfPackagesToDexopt + ": " + pkg.packageName);
9765 ActivityManager.getService().showBootMessage(
9766 mContext.getResources().getString(R.string.android_upgrading_apk,
9767 numberOfPackagesVisited, numberOfPackagesToDexopt), true);
9768 } catch (RemoteException e) {
9770 synchronized (mPackages) {
9771 mDexOptDialogShown = true;
9775 int pkgCompilationReason = compilationReason;
9776 if (useProfileForDexopt) {
9777 // Use background dexopt mode to try and use the profile. Note that this does not
9778 // guarantee usage of the profile.
9779 pkgCompilationReason = PackageManagerService.REASON_BACKGROUND_DEXOPT;
9782 if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
9783 mArtManagerService.compileLayouts(pkg);
9786 // checkProfiles is false to avoid merging profiles during boot which
9787 // might interfere with background compilation (b/28612421).
9788 // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
9789 // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
9790 // trade-off worth doing to save boot time work.
9791 int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
9792 if (compilationReason == REASON_FIRST_BOOT) {
9793 // TODO: This doesn't cover the upgrade case, we should check for this too.
9794 dexoptFlags |= DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE;
9796 int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
9798 pkgCompilationReason,
9801 switch (primaryDexOptStaus) {
9802 case PackageDexOptimizer.DEX_OPT_PERFORMED:
9803 numberOfPackagesOptimized++;
9805 case PackageDexOptimizer.DEX_OPT_SKIPPED:
9806 numberOfPackagesSkipped++;
9808 case PackageDexOptimizer.DEX_OPT_FAILED:
9809 numberOfPackagesFailed++;
9812 Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
9817 return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9818 numberOfPackagesFailed };
9822 public void notifyPackageUse(String packageName, int reason) {
9823 synchronized (mPackages) {
9824 final int callingUid = Binder.getCallingUid();
9825 final int callingUserId = UserHandle.getUserId(callingUid);
9826 if (getInstantAppPackageName(callingUid) != null) {
9827 if (!isCallerSameApp(packageName, callingUid)) {
9831 if (isInstantApp(packageName, callingUserId)) {
9835 notifyPackageUseLocked(packageName, reason);
9839 @GuardedBy("mPackages")
9840 public CheckPermissionDelegate getCheckPermissionDelegateLocked() {
9841 return mCheckPermissionDelegate;
9844 @GuardedBy("mPackages")
9845 public void setCheckPermissionDelegateLocked(CheckPermissionDelegate delegate) {
9846 mCheckPermissionDelegate = delegate;
9849 @GuardedBy("mPackages")
9850 private void notifyPackageUseLocked(String packageName, int reason) {
9851 final PackageParser.Package p = mPackages.get(packageName);
9855 p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
9859 public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
9860 List<String> classPaths, String loaderIsa) {
9861 int userId = UserHandle.getCallingUserId();
9862 ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
9864 Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
9865 + loadingPackageName + ", user=" + userId);
9868 mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
9872 public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
9873 IDexModuleRegisterCallback callback) {
9874 int userId = UserHandle.getCallingUserId();
9875 ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
9876 DexManager.RegisterDexModuleResult result;
9878 Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
9879 " calling user. package=" + packageName + ", user=" + userId);
9880 result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
9882 result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
9885 if (callback != null) {
9886 mHandler.post(() -> {
9888 callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
9889 } catch (RemoteException e) {
9890 Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
9897 * Ask the package manager to perform a dex-opt with the given compiler filter.
9899 * Note: exposed only for the shell command to allow moving packages explicitly to a
9903 public boolean performDexOptMode(String packageName,
9904 boolean checkProfiles, String targetCompilerFilter, boolean force,
9905 boolean bootComplete, String splitName) {
9906 int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
9907 (force ? DexoptOptions.DEXOPT_FORCE : 0) |
9908 (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
9909 return performDexOpt(new DexoptOptions(packageName, REASON_UNKNOWN,
9910 targetCompilerFilter, splitName, flags));
9914 * Ask the package manager to perform a dex-opt with the given compiler filter on the
9915 * secondary dex files belonging to the given package.
9917 * Note: exposed only for the shell command to allow moving packages explicitly to a
9921 public boolean performDexOptSecondary(String packageName, String compilerFilter,
9923 int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
9924 DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
9925 DexoptOptions.DEXOPT_BOOT_COMPLETE |
9926 (force ? DexoptOptions.DEXOPT_FORCE : 0);
9927 return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
9931 * Ask the package manager to compile layouts in the given package.
9934 public boolean compileLayouts(String packageName) {
9935 PackageParser.Package pkg;
9936 synchronized (mPackages) {
9937 pkg = mPackages.get(packageName);
9942 return mViewCompiler.compileLayouts(pkg);
9945 /*package*/ boolean performDexOpt(DexoptOptions options) {
9946 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9948 } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
9952 if (options.isDexoptOnlySecondaryDex()) {
9953 return mDexManager.dexoptSecondaryDex(options);
9955 int dexoptStatus = performDexOptWithStatus(options);
9956 return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9961 * Perform dexopt on the given package and return one of following result:
9962 * {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
9963 * {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
9964 * {@link PackageDexOptimizer#DEX_OPT_FAILED}
9966 /* package */ int performDexOptWithStatus(DexoptOptions options) {
9967 return performDexOptTraced(options);
9970 private int performDexOptTraced(DexoptOptions options) {
9971 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9973 return performDexOptInternal(options);
9975 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9979 // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9980 // if the package can now be considered up to date for the given filter.
9981 private int performDexOptInternal(DexoptOptions options) {
9982 PackageParser.Package p;
9983 synchronized (mPackages) {
9984 p = mPackages.get(options.getPackageName());
9986 // Package could not be found. Report failure.
9987 return PackageDexOptimizer.DEX_OPT_FAILED;
9989 mPackageUsage.maybeWriteAsync(mPackages);
9990 mCompilerStats.maybeWriteAsync();
9992 long callingId = Binder.clearCallingIdentity();
9994 synchronized (mInstallLock) {
9995 return performDexOptInternalWithDependenciesLI(p, options);
9998 Binder.restoreCallingIdentity(callingId);
10002 public ArraySet<String> getOptimizablePackages() {
10003 ArraySet<String> pkgs = new ArraySet<>();
10004 synchronized (mPackages) {
10005 for (PackageParser.Package p : mPackages.values()) {
10006 if (PackageDexOptimizer.canOptimizePackage(p)) {
10007 pkgs.add(p.packageName);
10014 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
10015 DexoptOptions options) {
10016 // Select the dex optimizer based on the force parameter.
10017 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
10018 // allocate an object here.
10019 PackageDexOptimizer pdo = options.isForce()
10020 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
10021 : mPackageDexOptimizer;
10023 // Dexopt all dependencies first. Note: we ignore the return value and march on
10025 // Note that we are going to call performDexOpt on those libraries as many times as
10026 // they are referenced in packages. When we do a batch of performDexOpt (for example
10027 // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
10028 // and the first package that uses the library will dexopt it. The
10029 // others will see that the compiled code for the library is up to date.
10030 Collection<SharedLibraryInfo> deps = findSharedLibraries(p);
10031 final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
10032 if (!deps.isEmpty()) {
10033 DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
10034 options.getCompilationReason(), options.getCompilerFilter(),
10035 options.getSplitName(),
10036 options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
10037 for (SharedLibraryInfo info : deps) {
10038 PackageParser.Package depPackage = null;
10039 synchronized (mPackages) {
10040 depPackage = mPackages.get(info.getPackageName());
10042 if (depPackage != null) {
10043 // TODO: Analyze and investigate if we (should) profile libraries.
10044 pdo.performDexOpt(depPackage, instructionSets,
10045 getOrCreateCompilerPackageStats(depPackage),
10046 mDexManager.getPackageUseInfoOrDefault(depPackage.packageName),
10049 // TODO(ngeoffray): Support dexopting system shared libraries.
10053 return pdo.performDexOpt(p, instructionSets,
10054 getOrCreateCompilerPackageStats(p),
10055 mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
10059 * Reconcile the information we have about the secondary dex files belonging to
10060 * {@code packageName} and the actual dex files. For all dex files that were
10061 * deleted, update the internal records and delete the generated oat files.
10064 public void reconcileSecondaryDexFiles(String packageName) {
10065 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10067 } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
10070 mDexManager.reconcileSecondaryDexFiles(packageName);
10073 // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
10074 // a reference there.
10075 /*package*/ DexManager getDexManager() {
10076 return mDexManager;
10080 * Execute the background dexopt job immediately.
10083 public boolean runBackgroundDexoptJob(@Nullable List<String> packageNames) {
10084 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10087 enforceSystemOrRootOrShell("runBackgroundDexoptJob");
10088 final long identity = Binder.clearCallingIdentity();
10090 return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
10092 Binder.restoreCallingIdentity(identity);
10096 private static List<SharedLibraryInfo> findSharedLibraries(PackageParser.Package p) {
10097 if (p.usesLibraryInfos != null) {
10098 ArrayList<SharedLibraryInfo> retValue = new ArrayList<>();
10099 Set<String> collectedNames = new HashSet<>();
10100 for (SharedLibraryInfo info : p.usesLibraryInfos) {
10101 findSharedLibrariesRecursive(info, retValue, collectedNames);
10105 return Collections.emptyList();
10109 private static void findSharedLibrariesRecursive(SharedLibraryInfo info,
10110 ArrayList<SharedLibraryInfo> collected, Set<String> collectedNames) {
10111 if (!collectedNames.contains(info.getName())) {
10112 collectedNames.add(info.getName());
10113 collected.add(info);
10115 if (info.getDependencies() != null) {
10116 for (SharedLibraryInfo dep : info.getDependencies()) {
10117 findSharedLibrariesRecursive(dep, collected, collectedNames);
10123 List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package pkg) {
10124 List<SharedLibraryInfo> deps = findSharedLibraries(pkg);
10125 if (!deps.isEmpty()) {
10126 ArrayList<PackageParser.Package> retValue = new ArrayList<>();
10127 synchronized (mPackages) {
10128 for (SharedLibraryInfo info : deps) {
10129 PackageParser.Package depPackage = mPackages.get(info.getPackageName());
10130 if (depPackage != null) {
10131 retValue.add(depPackage);
10137 return Collections.emptyList();
10142 private SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version) {
10143 return getSharedLibraryInfo(name, version, mSharedLibraries, null);
10147 private static SharedLibraryInfo getSharedLibraryInfo(String name, long version,
10148 Map<String, LongSparseArray<SharedLibraryInfo>> existingLibraries,
10149 @Nullable Map<String, LongSparseArray<SharedLibraryInfo>> newLibraries) {
10150 if (newLibraries != null) {
10151 final LongSparseArray<SharedLibraryInfo> versionedLib = newLibraries.get(name);
10152 SharedLibraryInfo info = null;
10153 if (versionedLib != null) {
10154 info = versionedLib.get(version);
10156 if (info != null) {
10160 final LongSparseArray<SharedLibraryInfo> versionedLib = existingLibraries.get(name);
10161 if (versionedLib == null) {
10164 return versionedLib.get(version);
10167 private SharedLibraryInfo getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
10168 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(
10169 pkg.staticSharedLibName);
10170 if (versionedLib == null) {
10173 long previousLibVersion = -1;
10174 final int versionCount = versionedLib.size();
10175 for (int i = 0; i < versionCount; i++) {
10176 final long libVersion = versionedLib.keyAt(i);
10177 if (libVersion < pkg.staticSharedLibVersion) {
10178 previousLibVersion = Math.max(previousLibVersion, libVersion);
10181 if (previousLibVersion >= 0) {
10182 return versionedLib.get(previousLibVersion);
10189 private PackageSetting getSharedLibLatestVersionSetting(@NonNull ScanResult scanResult) {
10190 PackageSetting sharedLibPackage = null;
10191 synchronized (mPackages) {
10192 final SharedLibraryInfo latestSharedLibraVersionLPr =
10193 getLatestSharedLibraVersionLPr(scanResult.pkgSetting.pkg);
10194 if (latestSharedLibraVersionLPr != null) {
10195 sharedLibPackage = mSettings.getPackageLPr(
10196 latestSharedLibraVersionLPr.getPackageName());
10199 return sharedLibPackage;
10202 public void shutdown() {
10203 mPackageUsage.writeNow(mPackages);
10204 mCompilerStats.writeNow();
10205 mDexManager.writePackageDexUsageNow();
10206 PackageWatchdog.getInstance(mContext).writeNow();
10208 // This is the last chance to write out pending restriction settings
10209 synchronized (mPackages) {
10210 if (mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
10211 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
10212 for (int userId : mDirtyUsers) {
10213 mSettings.writePackageRestrictionsLPr(userId);
10215 mDirtyUsers.clear();
10221 public void dumpProfiles(String packageName) {
10222 PackageParser.Package pkg;
10223 synchronized (mPackages) {
10224 pkg = mPackages.get(packageName);
10226 throw new IllegalArgumentException("Unknown package: " + packageName);
10229 /* Only the shell, root, or the app user should be able to dump profiles. */
10230 int callingUid = Binder.getCallingUid();
10231 if (callingUid != Process.SHELL_UID &&
10232 callingUid != Process.ROOT_UID &&
10233 callingUid != pkg.applicationInfo.uid) {
10234 throw new SecurityException("dumpProfiles");
10237 synchronized (mInstallLock) {
10238 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
10239 mArtManagerService.dumpProfiles(pkg);
10240 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10245 public void forceDexOpt(String packageName) {
10246 enforceSystemOrRoot("forceDexOpt");
10248 PackageParser.Package pkg;
10249 synchronized (mPackages) {
10250 pkg = mPackages.get(packageName);
10252 throw new IllegalArgumentException("Unknown package: " + packageName);
10256 synchronized (mInstallLock) {
10257 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
10259 // Whoever is calling forceDexOpt wants a compiled package.
10260 // Don't use profiles since that may cause compilation to be skipped.
10261 final int res = performDexOptInternalWithDependenciesLI(
10263 new DexoptOptions(packageName,
10264 getDefaultCompilerFilter(),
10265 DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
10267 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10268 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
10269 throw new IllegalStateException("Failed to dexopt: " + res);
10274 @GuardedBy("mPackages")
10275 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
10276 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10277 Slog.w(TAG, "Unable to update from " + oldPkg.name
10278 + " to " + newPkg.packageName
10279 + ": old package not in system partition");
10281 } else if (mPackages.get(oldPkg.name) != null) {
10282 Slog.w(TAG, "Unable to update from " + oldPkg.name
10283 + " to " + newPkg.packageName
10284 + ": old package still exists");
10290 @GuardedBy("mInstallLock")
10291 void removeCodePathLI(File codePath) {
10292 if (codePath.isDirectory()) {
10294 mInstaller.rmPackageDir(codePath.getAbsolutePath());
10295 } catch (InstallerException e) {
10296 Slog.w(TAG, "Failed to remove code path", e);
10303 private int[] resolveUserIds(int userId) {
10304 return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
10307 private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
10309 Slog.wtf(TAG, "Package was null!", new Throwable());
10312 clearAppDataLeafLIF(pkg, userId, flags);
10313 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10314 for (int i = 0; i < childCount; i++) {
10315 clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
10318 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
10321 private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
10322 final PackageSetting ps;
10323 synchronized (mPackages) {
10324 ps = mSettings.mPackages.get(pkg.packageName);
10326 for (int realUserId : resolveUserIds(userId)) {
10327 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
10329 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
10331 } catch (InstallerException e) {
10332 Slog.w(TAG, String.valueOf(e));
10337 private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
10339 Slog.wtf(TAG, "Package was null!", new Throwable());
10342 destroyAppDataLeafLIF(pkg, userId, flags);
10343 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10344 for (int i = 0; i < childCount; i++) {
10345 destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
10349 private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
10350 final PackageSetting ps;
10351 synchronized (mPackages) {
10352 ps = mSettings.mPackages.get(pkg.packageName);
10354 for (int realUserId : resolveUserIds(userId)) {
10355 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
10357 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
10359 } catch (InstallerException e) {
10360 Slog.w(TAG, String.valueOf(e));
10362 mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
10366 private void destroyAppProfilesLIF(PackageParser.Package pkg) {
10368 Slog.wtf(TAG, "Package was null!", new Throwable());
10371 destroyAppProfilesLeafLIF(pkg);
10372 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10373 for (int i = 0; i < childCount; i++) {
10374 destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
10378 private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
10380 mInstaller.destroyAppProfiles(pkg.packageName);
10381 } catch (InstallerException e) {
10382 Slog.w(TAG, String.valueOf(e));
10386 private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
10388 Slog.wtf(TAG, "Package was null!", new Throwable());
10391 mArtManagerService.clearAppProfiles(pkg);
10392 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10393 for (int i = 0; i < childCount; i++) {
10394 mArtManagerService.clearAppProfiles(pkg.childPackages.get(i));
10398 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
10399 long lastUpdateTime) {
10400 // Set parent install/update time
10401 PackageSetting ps = (PackageSetting) pkg.mExtras;
10403 ps.firstInstallTime = firstInstallTime;
10404 ps.lastUpdateTime = lastUpdateTime;
10406 // Set children install/update time
10407 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10408 for (int i = 0; i < childCount; i++) {
10409 PackageParser.Package childPkg = pkg.childPackages.get(i);
10410 ps = (PackageSetting) childPkg.mExtras;
10412 ps.firstInstallTime = firstInstallTime;
10413 ps.lastUpdateTime = lastUpdateTime;
10418 @GuardedBy("mPackages")
10419 private void applyDefiningSharedLibraryUpdateLocked(
10420 PackageParser.Package pkg, SharedLibraryInfo libInfo,
10421 BiConsumer<SharedLibraryInfo, SharedLibraryInfo> action) {
10422 // Note that libraries defined by this package may be null if:
10423 // - Package manager was unable to create the shared library. The package still
10424 // gets installed, but the shared library does not get created.
10426 // - Package manager is in a state where package isn't scanned yet. This will
10427 // get called again after scanning to fix the dependencies.
10428 if (pkg.isLibrary()) {
10429 if (pkg.staticSharedLibName != null) {
10430 SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr(
10431 pkg.staticSharedLibName, pkg.staticSharedLibVersion);
10432 if (definedLibrary != null) {
10433 action.accept(definedLibrary, libInfo);
10436 for (String libraryName : pkg.libraryNames) {
10437 SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr(
10438 libraryName, SharedLibraryInfo.VERSION_UNDEFINED);
10439 if (definedLibrary != null) {
10440 action.accept(definedLibrary, libInfo);
10447 @GuardedBy("mPackages")
10448 private void addSharedLibraryLPr(PackageParser.Package pkg, Set<String> usesLibraryFiles,
10449 SharedLibraryInfo libInfo, PackageParser.Package changingLib) {
10450 if (libInfo.getPath() != null) {
10451 usesLibraryFiles.add(libInfo.getPath());
10454 PackageParser.Package p = mPackages.get(libInfo.getPackageName());
10455 if (changingLib != null && changingLib.packageName.equals(libInfo.getPackageName())) {
10456 // If we are doing this while in the middle of updating a library apk,
10457 // then we need to make sure to use that new apk for determining the
10458 // dependencies here. (We haven't yet finished committing the new apk
10459 // to the package manager state.)
10460 if (p == null || p.packageName.equals(changingLib.packageName)) {
10465 usesLibraryFiles.addAll(p.getAllCodePaths());
10466 // If the package provides libraries, add the dependency to them.
10467 applyDefiningSharedLibraryUpdateLocked(pkg, libInfo, (definingLibrary, dependency) -> {
10468 definingLibrary.addDependency(dependency);
10470 if (p.usesLibraryFiles != null) {
10471 Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
10476 @GuardedBy("mPackages")
10477 private void updateSharedLibrariesLocked(PackageParser.Package pkg,
10478 PackageParser.Package changingLib, Map<String, PackageParser.Package> availablePackages)
10479 throws PackageManagerException {
10480 final ArrayList<SharedLibraryInfo> sharedLibraryInfos =
10481 collectSharedLibraryInfos(pkg, availablePackages, mSharedLibraries, null);
10482 executeSharedLibrariesUpdateLPr(pkg, changingLib, sharedLibraryInfos);
10485 private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(PackageParser.Package pkg,
10486 Map<String, PackageParser.Package> availablePackages,
10487 @NonNull final Map<String, LongSparseArray<SharedLibraryInfo>> existingLibraries,
10488 @Nullable final Map<String, LongSparseArray<SharedLibraryInfo>> newLibraries)
10489 throws PackageManagerException {
10493 // The collection used here must maintain the order of addition (so
10494 // that libraries are searched in the correct order) and must have no
10496 ArrayList<SharedLibraryInfo> usesLibraryInfos = null;
10497 if (pkg.usesLibraries != null) {
10498 usesLibraryInfos = collectSharedLibraryInfos(pkg.usesLibraries, null, null,
10499 pkg.packageName, true, pkg.applicationInfo.targetSdkVersion, null,
10500 availablePackages, existingLibraries, newLibraries);
10502 if (pkg.usesStaticLibraries != null) {
10503 usesLibraryInfos = collectSharedLibraryInfos(pkg.usesStaticLibraries,
10504 pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
10505 pkg.packageName, true, pkg.applicationInfo.targetSdkVersion, usesLibraryInfos,
10506 availablePackages, existingLibraries, newLibraries);
10508 if (pkg.usesOptionalLibraries != null) {
10509 usesLibraryInfos = collectSharedLibraryInfos(pkg.usesOptionalLibraries,
10510 null, null, pkg.packageName, false, pkg.applicationInfo.targetSdkVersion,
10511 usesLibraryInfos, availablePackages, existingLibraries, newLibraries);
10513 return usesLibraryInfos;
10516 private void executeSharedLibrariesUpdateLPr(PackageParser.Package pkg,
10517 PackageParser.Package changingLib, ArrayList<SharedLibraryInfo> usesLibraryInfos) {
10518 // If the package provides libraries, clear their old dependencies.
10519 // This method will set them up again.
10520 applyDefiningSharedLibraryUpdateLocked(pkg, null, (definingLibrary, dependency) -> {
10521 definingLibrary.clearDependencies();
10523 if (usesLibraryInfos != null) {
10524 pkg.usesLibraryInfos = usesLibraryInfos;
10525 // Use LinkedHashSet to preserve the order of files added to
10526 // usesLibraryFiles while eliminating duplicates.
10527 Set<String> usesLibraryFiles = new LinkedHashSet<>();
10528 for (SharedLibraryInfo libInfo : usesLibraryInfos) {
10529 addSharedLibraryLPr(pkg, usesLibraryFiles, libInfo, changingLib);
10531 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
10533 pkg.usesLibraryInfos = null;
10534 pkg.usesLibraryFiles = null;
10538 @GuardedBy("mPackages")
10539 private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(
10540 @NonNull List<String> requestedLibraries,
10541 @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
10542 @NonNull String packageName, boolean required, int targetSdk,
10543 @Nullable ArrayList<SharedLibraryInfo> outUsedLibraries,
10544 @NonNull final Map<String, PackageParser.Package> availablePackages,
10545 @NonNull final Map<String, LongSparseArray<SharedLibraryInfo>> existingLibraries,
10546 @Nullable final Map<String, LongSparseArray<SharedLibraryInfo>> newLibraries)
10547 throws PackageManagerException {
10548 final int libCount = requestedLibraries.size();
10549 for (int i = 0; i < libCount; i++) {
10550 final String libName = requestedLibraries.get(i);
10551 final long libVersion = requiredVersions != null ? requiredVersions[i]
10552 : SharedLibraryInfo.VERSION_UNDEFINED;
10553 final SharedLibraryInfo libraryInfo = getSharedLibraryInfo(libName, libVersion,
10554 existingLibraries, newLibraries);
10555 if (libraryInfo == null) {
10557 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10558 "Package " + packageName + " requires unavailable shared library "
10559 + libName + "; failing!");
10560 } else if (DEBUG_SHARED_LIBRARIES) {
10561 Slog.i(TAG, "Package " + packageName
10562 + " desires unavailable shared library "
10563 + libName + "; ignoring!");
10566 if (requiredVersions != null && requiredCertDigests != null) {
10567 if (libraryInfo.getLongVersion() != requiredVersions[i]) {
10568 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10569 "Package " + packageName + " requires unavailable static shared"
10570 + " library " + libName + " version "
10571 + libraryInfo.getLongVersion() + "; failing!");
10573 PackageParser.Package libPkg =
10574 availablePackages.get(libraryInfo.getPackageName());
10575 if (libPkg == null) {
10576 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10577 "Package " + packageName + " requires unavailable static shared"
10578 + " library; failing!");
10580 final String[] expectedCertDigests = requiredCertDigests[i];
10581 if (expectedCertDigests.length > 1) {
10582 // For apps targeting O MR1 we require explicit enumeration of all certs.
10583 final String[] libCertDigests = (targetSdk >= Build.VERSION_CODES.O_MR1)
10584 ? PackageUtils.computeSignaturesSha256Digests(
10585 libPkg.mSigningDetails.signatures)
10586 : PackageUtils.computeSignaturesSha256Digests(
10587 new Signature[]{libPkg.mSigningDetails.signatures[0]});
10589 // Take a shortcut if sizes don't match. Note that if an app doesn't
10590 // target O we don't parse the "additional-certificate" tags similarly
10591 // how we only consider all certs only for apps targeting O (see above).
10592 // Therefore, the size check is safe to make.
10593 if (expectedCertDigests.length != libCertDigests.length) {
10594 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10595 "Package " + packageName + " requires differently signed" +
10596 " static shared library; failing!");
10599 // Use a predictable order as signature order may vary
10600 Arrays.sort(libCertDigests);
10601 Arrays.sort(expectedCertDigests);
10603 final int certCount = libCertDigests.length;
10604 for (int j = 0; j < certCount; j++) {
10605 if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
10606 throw new PackageManagerException(
10607 INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10608 "Package " + packageName + " requires differently signed" +
10609 " static shared library; failing!");
10613 // lib signing cert could have rotated beyond the one expected, check to see
10614 // if the new one has been blessed by the old
10615 if (!libPkg.mSigningDetails.hasSha256Certificate(
10616 ByteStringUtils.fromHexToByteArray(expectedCertDigests[0]))) {
10617 throw new PackageManagerException(
10618 INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10619 "Package " + packageName + " requires differently signed" +
10620 " static shared library; failing!");
10624 if (outUsedLibraries == null) {
10625 outUsedLibraries = new ArrayList<>();
10627 outUsedLibraries.add(libraryInfo);
10630 return outUsedLibraries;
10633 private static boolean hasString(List<String> list, List<String> which) {
10634 if (list == null || which == null) {
10637 for (int i=list.size()-1; i>=0; i--) {
10638 for (int j=which.size()-1; j>=0; j--) {
10639 if (which.get(j).equals(list.get(i))) {
10647 @GuardedBy("mPackages")
10648 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLocked(
10649 PackageParser.Package updatedPkg,
10650 Map<String, PackageParser.Package> availablePackages) {
10651 ArrayList<PackageParser.Package> resultList = null;
10652 // Set of all descendants of a library; used to eliminate cycles
10653 ArraySet<String> descendants = null;
10654 // The current list of packages that need updating
10655 ArrayList<PackageParser.Package> needsUpdating = null;
10656 if (updatedPkg != null) {
10657 needsUpdating = new ArrayList<>(1);
10658 needsUpdating.add(updatedPkg);
10661 final PackageParser.Package changingPkg =
10662 (needsUpdating == null) ? null : needsUpdating.remove(0);
10663 for (int i = mPackages.size() - 1; i >= 0; --i) {
10664 final PackageParser.Package pkg = mPackages.valueAt(i);
10665 if (changingPkg != null
10666 && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
10667 && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
10668 && !ArrayUtils.contains(pkg.usesStaticLibraries,
10669 changingPkg.staticSharedLibName)) {
10672 if (resultList == null) {
10673 resultList = new ArrayList<>();
10675 resultList.add(pkg);
10676 // if we're updating a shared library, all of its descendants must be updated
10677 if (changingPkg != null) {
10678 if (descendants == null) {
10679 descendants = new ArraySet<>();
10681 if (!descendants.contains(pkg.packageName)) {
10682 descendants.add(pkg.packageName);
10683 needsUpdating.add(pkg);
10687 updateSharedLibrariesLocked(pkg, changingPkg, availablePackages);
10688 } catch (PackageManagerException e) {
10689 // If a system app update or an app and a required lib missing we
10690 // delete the package and for updated system apps keep the data as
10691 // it is better for the user to reinstall than to be in an limbo
10692 // state. Also libs disappearing under an app should never happen
10694 if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) {
10695 final int flags = pkg.isUpdatedSystemApp()
10696 ? PackageManager.DELETE_KEEP_DATA : 0;
10697 deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
10698 flags , null, true, null);
10700 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
10703 } while (needsUpdating != null && needsUpdating.size() > 0);
10707 @GuardedBy({"mInstallLock", "mPackages"})
10708 private List<ScanResult> scanPackageTracedLI(PackageParser.Package pkg,
10709 final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
10710 @Nullable UserHandle user) throws PackageManagerException {
10711 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
10712 // If the package has children and this is the first dive in the function
10713 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
10714 // whether all packages (parent and children) would be successfully scanned
10715 // before the actual scan since scanning mutates internal state and we want
10716 // to atomically install the package and its children.
10717 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10718 if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
10719 scanFlags |= SCAN_CHECK_ONLY;
10722 scanFlags &= ~SCAN_CHECK_ONLY;
10725 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10726 final List<ScanResult> scanResults = new ArrayList<>(1 + childCount);
10729 scanResults.add(scanPackageNewLI(pkg, parseFlags, scanFlags, currentTime, user));
10730 // Scan the children
10731 for (int i = 0; i < childCount; i++) {
10732 PackageParser.Package childPkg = pkg.childPackages.get(i);
10733 scanResults.add(scanPackageNewLI(childPkg, parseFlags,
10734 scanFlags, currentTime, user));
10737 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10740 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10741 return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user);
10744 return scanResults;
10747 /** The result of a package scan. */
10748 private static class ScanResult {
10749 /** The request that initiated the scan that produced this result. */
10750 public final ScanRequest request;
10751 /** Whether or not the package scan was successful */
10752 public final boolean success;
10754 * Whether or not the original PackageSetting needs to be updated with this result on
10757 public final boolean existingSettingCopied;
10759 * The final package settings. This may be the same object passed in
10760 * the {@link ScanRequest}, but, with modified values.
10762 @Nullable public final PackageSetting pkgSetting;
10763 /** ABI code paths that have changed in the package scan */
10764 @Nullable public final List<String> changedAbiCodePath;
10766 public final SharedLibraryInfo staticSharedLibraryInfo;
10768 public final List<SharedLibraryInfo> dynamicSharedLibraryInfos;
10771 ScanRequest request, boolean success,
10772 @Nullable PackageSetting pkgSetting,
10773 @Nullable List<String> changedAbiCodePath, boolean existingSettingCopied,
10774 SharedLibraryInfo staticSharedLibraryInfo,
10775 List<SharedLibraryInfo> dynamicSharedLibraryInfos) {
10776 this.request = request;
10777 this.success = success;
10778 this.pkgSetting = pkgSetting;
10779 this.changedAbiCodePath = changedAbiCodePath;
10780 this.existingSettingCopied = existingSettingCopied;
10781 this.staticSharedLibraryInfo = staticSharedLibraryInfo;
10782 this.dynamicSharedLibraryInfos = dynamicSharedLibraryInfos;
10786 /** A package to be scanned */
10787 private static class ScanRequest {
10788 /** The parsed package */
10789 @NonNull public final PackageParser.Package pkg;
10790 /** The package this package replaces */
10791 @Nullable public final PackageParser.Package oldPkg;
10792 /** Shared user settings, if the package has a shared user */
10793 @Nullable public final SharedUserSetting sharedUserSetting;
10795 * Package settings of the currently installed version.
10796 * <p><em>IMPORTANT:</em> The contents of this object may be modified
10799 @Nullable public final PackageSetting pkgSetting;
10800 /** A copy of the settings for the currently installed version */
10801 @Nullable public final PackageSetting oldPkgSetting;
10802 /** Package settings for the disabled version on the /system partition */
10803 @Nullable public final PackageSetting disabledPkgSetting;
10804 /** Package settings for the installed version under its original package name */
10805 @Nullable public final PackageSetting originalPkgSetting;
10806 /** The real package name of a renamed application */
10807 @Nullable public final String realPkgName;
10808 public final @ParseFlags int parseFlags;
10809 public final @ScanFlags int scanFlags;
10810 /** The user for which the package is being scanned */
10811 @Nullable public final UserHandle user;
10812 /** Whether or not the platform package is being scanned */
10813 public final boolean isPlatformPackage;
10814 public ScanRequest(
10815 @NonNull PackageParser.Package pkg,
10816 @Nullable SharedUserSetting sharedUserSetting,
10817 @Nullable PackageParser.Package oldPkg,
10818 @Nullable PackageSetting pkgSetting,
10819 @Nullable PackageSetting disabledPkgSetting,
10820 @Nullable PackageSetting originalPkgSetting,
10821 @Nullable String realPkgName,
10822 @ParseFlags int parseFlags,
10823 @ScanFlags int scanFlags,
10824 boolean isPlatformPackage,
10825 @Nullable UserHandle user) {
10827 this.oldPkg = oldPkg;
10828 this.pkgSetting = pkgSetting;
10829 this.sharedUserSetting = sharedUserSetting;
10830 this.oldPkgSetting = pkgSetting == null ? null : new PackageSetting(pkgSetting);
10831 this.disabledPkgSetting = disabledPkgSetting;
10832 this.originalPkgSetting = originalPkgSetting;
10833 this.realPkgName = realPkgName;
10834 this.parseFlags = parseFlags;
10835 this.scanFlags = scanFlags;
10836 this.isPlatformPackage = isPlatformPackage;
10842 * Returns the actual scan flags depending upon the state of the other settings.
10843 * <p>Updated system applications will not have the following flags set
10844 * by default and need to be adjusted after the fact:
10846 * <li>{@link #SCAN_AS_SYSTEM}</li>
10847 * <li>{@link #SCAN_AS_PRIVILEGED}</li>
10848 * <li>{@link #SCAN_AS_OEM}</li>
10849 * <li>{@link #SCAN_AS_VENDOR}</li>
10850 * <li>{@link #SCAN_AS_PRODUCT}</li>
10851 * <li>{@link #SCAN_AS_PRODUCT_SERVICES}</li>
10852 * <li>{@link #SCAN_AS_INSTANT_APP}</li>
10853 * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
10854 * <li>{@link #SCAN_AS_ODM}</li>
10857 private @ScanFlags int adjustScanFlags(@ScanFlags int scanFlags,
10858 PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user,
10859 PackageParser.Package pkg) {
10861 // TODO(patb): Do away entirely with disabledPkgSetting here. PkgSetting will always contain
10862 // the correct isSystem value now that we don't disable system packages before scan.
10863 final PackageSetting systemPkgSetting =
10864 (scanFlags & SCAN_NEW_INSTALL) != 0 && disabledPkgSetting == null
10865 && pkgSetting != null && pkgSetting.isSystem()
10867 : disabledPkgSetting;
10868 if (systemPkgSetting != null) {
10869 // updated system application, must at least have SCAN_AS_SYSTEM
10870 scanFlags |= SCAN_AS_SYSTEM;
10871 if ((systemPkgSetting.pkgPrivateFlags
10872 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
10873 scanFlags |= SCAN_AS_PRIVILEGED;
10875 if ((systemPkgSetting.pkgPrivateFlags
10876 & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
10877 scanFlags |= SCAN_AS_OEM;
10879 if ((systemPkgSetting.pkgPrivateFlags
10880 & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
10881 scanFlags |= SCAN_AS_VENDOR;
10883 if ((systemPkgSetting.pkgPrivateFlags
10884 & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0) {
10885 scanFlags |= SCAN_AS_PRODUCT;
10887 if ((systemPkgSetting.pkgPrivateFlags
10888 & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0) {
10889 scanFlags |= SCAN_AS_PRODUCT_SERVICES;
10891 if ((systemPkgSetting.pkgPrivateFlags
10892 & ApplicationInfo.PRIVATE_FLAG_ODM) != 0) {
10893 scanFlags |= SCAN_AS_ODM;
10896 if (pkgSetting != null) {
10897 final int userId = ((user == null) ? 0 : user.getIdentifier());
10898 if (pkgSetting.getInstantApp(userId)) {
10899 scanFlags |= SCAN_AS_INSTANT_APP;
10901 if (pkgSetting.getVirtulalPreload(userId)) {
10902 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
10906 // Scan as privileged apps that share a user with a priv-app.
10907 final boolean skipVendorPrivilegeScan = ((scanFlags & SCAN_AS_VENDOR) != 0)
10908 && SystemProperties.getInt("ro.vndk.version", 28) < 28;
10909 if (((scanFlags & SCAN_AS_PRIVILEGED) == 0)
10910 && !pkg.isPrivileged()
10911 && (pkg.mSharedUserId != null)
10912 && !skipVendorPrivilegeScan) {
10913 SharedUserSetting sharedUserSetting = null;
10915 sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false);
10916 } catch (PackageManagerException ignore) {}
10917 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
10918 // Exempt SharedUsers signed with the platform key.
10919 // TODO(b/72378145) Fix this exemption. Force signature apps
10920 // to whitelist their privileged permissions just like other
10922 synchronized (mPackages) {
10923 PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
10924 if ((compareSignatures(platformPkgSetting.signatures.mSigningDetails.signatures,
10925 pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH)) {
10926 scanFlags |= SCAN_AS_PRIVILEGED;
10935 // TODO: scanPackageNewLI() and scanPackageOnly() should be merged. But, first, commiting
10936 // the results / removing app data needs to be moved up a level to the callers of this
10937 // method. Also, we need to solve the problem of potentially creating a new shared user
10938 // setting. That can probably be done later and patch things up after the fact.
10939 @GuardedBy({"mInstallLock", "mPackages"})
10940 private ScanResult scanPackageNewLI(@NonNull PackageParser.Package pkg,
10941 final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
10942 @Nullable UserHandle user) throws PackageManagerException {
10944 final String renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
10945 final String realPkgName = getRealPackageName(pkg, renamedPkgName);
10946 if (realPkgName != null) {
10947 ensurePackageRenamed(pkg, renamedPkgName);
10949 final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
10950 final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.packageName);
10951 final PackageSetting disabledPkgSetting =
10952 mSettings.getDisabledSystemPkgLPr(pkg.packageName);
10954 if (mTransferedPackages.contains(pkg.packageName)) {
10955 Slog.w(TAG, "Package " + pkg.packageName
10956 + " was transferred to another, but its .apk remains");
10959 scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, pkg);
10960 synchronized (mPackages) {
10961 applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage);
10962 assertPackageIsValid(pkg, parseFlags, scanFlags);
10964 SharedUserSetting sharedUserSetting = null;
10965 if (pkg.mSharedUserId != null) {
10966 // SIDE EFFECTS; may potentially allocate a new shared user
10967 sharedUserSetting = mSettings.getSharedUserLPw(
10968 pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
10969 if (DEBUG_PACKAGE_SCANNING) {
10970 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
10971 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
10972 + " (uid=" + sharedUserSetting.userId + "):"
10973 + " packages=" + sharedUserSetting.packages);
10976 final ScanRequest request = new ScanRequest(pkg, sharedUserSetting,
10977 pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting,
10978 originalPkgSetting, realPkgName, parseFlags, scanFlags,
10979 (pkg == mPlatformPackage), user);
10980 return scanPackageOnlyLI(request, mFactoryTest, currentTime);
10986 * Prepares the system to commit a {@link ScanResult} in a way that will not fail by registering
10987 * the app ID required for reconcile.
10988 * @return {@code true} if a new app ID was registered and will need to be cleaned up on
10991 private boolean optimisticallyRegisterAppId(@NonNull ScanResult result)
10992 throws PackageManagerException {
10993 if (!result.existingSettingCopied) {
10994 // THROWS: when we can't allocate a user id. add call to check if there's
10995 // enough space to ensure we won't throw; otherwise, don't modify state
10996 return mSettings.registerAppIdLPw(result.pkgSetting);
11002 * Reverts any app ID creation that were made by
11003 * {@link #optimisticallyRegisterAppId(ScanResult)}. Note: this is only necessary if the
11004 * referenced method returned true.
11006 private void cleanUpAppIdCreation(@NonNull ScanResult result) {
11007 // iff we've acquired an app ID for a new package setting, remove it so that it can be
11008 // acquired by another request.
11009 if (result.pkgSetting.appId > 0) {
11010 mSettings.removeAppIdLPw(result.pkgSetting.appId);
11015 * Commits the package scan and modifies system state.
11016 * <p><em>WARNING:</em> The method may throw an excpetion in the middle
11017 * of committing the package, leaving the system in an inconsistent state.
11018 * This needs to be fixed so, once we get to this point, no errors are
11019 * possible and the system is not left in an inconsistent state.
11021 @GuardedBy({"mPackages", "mInstallLock"})
11022 private void commitReconciledScanResultLocked(@NonNull ReconciledPackage reconciledPkg) {
11023 final ScanResult result = reconciledPkg.scanResult;
11024 final ScanRequest request = result.request;
11025 final PackageParser.Package pkg = request.pkg;
11026 final PackageParser.Package oldPkg = request.oldPkg;
11027 final @ParseFlags int parseFlags = request.parseFlags;
11028 final @ScanFlags int scanFlags = request.scanFlags;
11029 final PackageSetting oldPkgSetting = request.oldPkgSetting;
11030 final PackageSetting originalPkgSetting = request.originalPkgSetting;
11031 final UserHandle user = request.user;
11032 final String realPkgName = request.realPkgName;
11033 final List<String> changedAbiCodePath = result.changedAbiCodePath;
11034 final PackageSetting pkgSetting;
11035 if (request.pkgSetting != null && request.pkgSetting.sharedUser != null
11036 && request.pkgSetting.sharedUser != result.pkgSetting.sharedUser) {
11037 // shared user changed, remove from old shared user
11038 request.pkgSetting.sharedUser.removePackage(request.pkgSetting);
11040 if (result.existingSettingCopied) {
11041 pkgSetting = request.pkgSetting;
11042 pkgSetting.updateFrom(result.pkgSetting);
11043 pkg.mExtras = pkgSetting;
11045 pkgSetting = result.pkgSetting;
11046 if (originalPkgSetting != null) {
11047 mSettings.addRenamedPackageLPw(pkg.packageName, originalPkgSetting.name);
11049 if (originalPkgSetting != null && (scanFlags & SCAN_CHECK_ONLY) == 0) {
11050 mTransferedPackages.add(originalPkgSetting.name);
11053 if (pkgSetting.sharedUser != null) {
11054 pkgSetting.sharedUser.addPackage(pkgSetting);
11056 // TODO(toddke): Consider a method specifically for modifying the Package object
11057 // post scan; or, moving this stuff out of the Package object since it has nothing
11058 // to do with the package on disk.
11059 // We need to have this here because addUserToSettingLPw() is sometimes responsible
11060 // for creating the application ID. If we did this earlier, we would be saving the
11062 pkg.applicationInfo.uid = pkgSetting.appId;
11064 mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
11066 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realPkgName != null) {
11067 mTransferedPackages.add(pkg.packageName);
11070 if (reconciledPkg.collectedSharedLibraryInfos != null) {
11071 executeSharedLibrariesUpdateLPr(pkg, null, reconciledPkg.collectedSharedLibraryInfos);
11074 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
11075 if (reconciledPkg.removeAppKeySetData) {
11076 ksms.removeAppKeySetDataLPw(pkg.packageName);
11078 if (reconciledPkg.sharedUserSignaturesChanged) {
11079 pkgSetting.sharedUser.signaturesChanged = Boolean.TRUE;
11080 pkgSetting.sharedUser.signatures.mSigningDetails = reconciledPkg.signingDetails;
11082 pkgSetting.signatures.mSigningDetails = reconciledPkg.signingDetails;
11084 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
11085 // This package wants to adopt ownership of permissions from
11086 // another package.
11087 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
11088 final String origName = pkg.mAdoptPermissions.get(i);
11089 final PackageSetting orig = mSettings.getPackageLPr(origName);
11090 if (orig != null) {
11091 if (verifyPackageUpdateLPr(orig, pkg)) {
11092 Slog.i(TAG, "Adopting permissions from " + origName + " to "
11093 + pkg.packageName);
11094 mSettings.mPermissions.transferPermissions(origName, pkg.packageName);
11100 if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
11101 for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
11102 final String codePathString = changedAbiCodePath.get(i);
11104 mInstaller.rmdex(codePathString,
11105 getDexCodeInstructionSet(getPreferredInstructionSet()));
11106 } catch (InstallerException ignored) {
11111 if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
11112 if (oldPkgSetting != null) {
11113 synchronized (mPackages) {
11114 mSettings.mPackages.put(oldPkgSetting.name, oldPkgSetting);
11118 final int userId = user == null ? 0 : user.getIdentifier();
11119 // Modify state for the given package setting
11120 commitPackageSettings(pkg, oldPkg, pkgSetting, scanFlags,
11121 (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/, reconciledPkg);
11122 if (pkgSetting.getInstantApp(userId)) {
11123 mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
11129 * Returns the "real" name of the package.
11130 * <p>This may differ from the package's actual name if the application has already
11131 * been installed under one of this package's original names.
11133 private static @Nullable String getRealPackageName(@NonNull PackageParser.Package pkg,
11134 @Nullable String renamedPkgName) {
11135 if (isPackageRenamed(pkg, renamedPkgName)) {
11136 return pkg.mRealPackage;
11141 /** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */
11142 private static boolean isPackageRenamed(@NonNull PackageParser.Package pkg,
11143 @Nullable String renamedPkgName) {
11144 return pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(renamedPkgName);
11148 * Returns the original package setting.
11149 * <p>A package can migrate its name during an update. In this scenario, a package
11150 * designates a set of names that it considers as one of its original names.
11151 * <p>An original package must be signed identically and it must have the same
11152 * shared user [if any].
11154 @GuardedBy("mPackages")
11155 private @Nullable PackageSetting getOriginalPackageLocked(@NonNull PackageParser.Package pkg,
11156 @Nullable String renamedPkgName) {
11157 if (!isPackageRenamed(pkg, renamedPkgName)) {
11160 for (int i = pkg.mOriginalPackages.size() - 1; i >= 0; --i) {
11161 final PackageSetting originalPs =
11162 mSettings.getPackageLPr(pkg.mOriginalPackages.get(i));
11163 if (originalPs != null) {
11164 // the package is already installed under its original name...
11165 // but, should we use it?
11166 if (!verifyPackageUpdateLPr(originalPs, pkg)) {
11167 // the new package is incompatible with the original
11169 } else if (originalPs.sharedUser != null) {
11170 if (!originalPs.sharedUser.name.equals(pkg.mSharedUserId)) {
11171 // the shared user id is incompatible with the original
11172 Slog.w(TAG, "Unable to migrate data from " + originalPs.name
11173 + " to " + pkg.packageName + ": old uid "
11174 + originalPs.sharedUser.name
11175 + " differs from " + pkg.mSharedUserId);
11178 // TODO: Add case when shared user id is added [b/28144775]
11180 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
11181 + pkg.packageName + " to old name " + originalPs.name);
11190 * Renames the package if it was installed under a different name.
11191 * <p>When we've already installed the package under an original name, update
11192 * the new package so we can continue to have the old name.
11194 private static void ensurePackageRenamed(@NonNull PackageParser.Package pkg,
11195 @NonNull String renamedPackageName) {
11196 if (pkg.mOriginalPackages == null
11197 || !pkg.mOriginalPackages.contains(renamedPackageName)
11198 || pkg.packageName.equals(renamedPackageName)) {
11201 pkg.setPackageName(renamedPackageName);
11205 * Just scans the package without any side effects.
11206 * <p>Not entirely true at the moment. There is still one side effect -- this
11207 * method potentially modifies a live {@link PackageSetting} object representing
11208 * the package being scanned. This will be resolved in the future.
11210 * @param request Information about the package to be scanned
11211 * @param isUnderFactoryTest Whether or not the device is under factory test
11212 * @param currentTime The current time, in millis
11213 * @return The results of the scan
11215 @GuardedBy("mInstallLock")
11216 private static @NonNull ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
11217 boolean isUnderFactoryTest, long currentTime)
11218 throws PackageManagerException {
11219 final PackageParser.Package pkg = request.pkg;
11220 PackageSetting pkgSetting = request.pkgSetting;
11221 final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
11222 final PackageSetting originalPkgSetting = request.originalPkgSetting;
11223 final @ParseFlags int parseFlags = request.parseFlags;
11224 final @ScanFlags int scanFlags = request.scanFlags;
11225 final String realPkgName = request.realPkgName;
11226 final SharedUserSetting sharedUserSetting = request.sharedUserSetting;
11227 final UserHandle user = request.user;
11228 final boolean isPlatformPackage = request.isPlatformPackage;
11230 List<String> changedAbiCodePath = null;
11232 if (DEBUG_PACKAGE_SCANNING) {
11233 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
11234 Log.d(TAG, "Scanning package " + pkg.packageName);
11237 // Initialize package source and resource directories
11238 final File scanFile = new File(pkg.codePath);
11239 final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
11240 final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
11242 // We keep references to the derived CPU Abis from settings in oder to reuse
11243 // them in the case where we're not upgrading or booting for the first time.
11244 String primaryCpuAbiFromSettings = null;
11245 String secondaryCpuAbiFromSettings = null;
11246 boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
11247 if (!needToDeriveAbi) {
11248 if (pkgSetting != null) {
11249 primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
11250 secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
11252 // Re-scanning a system package after uninstalling updates; need to derive ABI
11253 needToDeriveAbi = true;
11257 if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) {
11258 PackageManagerService.reportSettingsProblem(Log.WARN,
11259 "Package " + pkg.packageName + " shared user changed from "
11260 + (pkgSetting.sharedUser != null
11261 ? pkgSetting.sharedUser.name : "<nothing>")
11263 + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
11264 + "; replacing with new");
11268 String[] usesStaticLibraries = null;
11269 if (pkg.usesStaticLibraries != null) {
11270 usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
11271 pkg.usesStaticLibraries.toArray(usesStaticLibraries);
11273 final boolean createNewPackage = (pkgSetting == null);
11274 if (createNewPackage) {
11275 final String parentPackageName = (pkg.parentPackage != null)
11276 ? pkg.parentPackage.packageName : null;
11277 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
11278 final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
11279 // REMOVE SharedUserSetting from method; update in a separate call
11280 pkgSetting = Settings.createNewSetting(pkg.packageName, originalPkgSetting,
11281 disabledPkgSetting, realPkgName, sharedUserSetting, destCodeFile,
11282 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
11283 pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
11284 pkg.mVersionCode, pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
11285 user, true /*allowInstall*/, instantApp, virtualPreload,
11286 parentPackageName, pkg.getChildPackageNames(),
11287 UserManagerService.getInstance(), usesStaticLibraries,
11288 pkg.usesStaticLibrariesVersions);
11290 // make a deep copy to avoid modifying any existing system state.
11291 pkgSetting = new PackageSetting(pkgSetting);
11292 pkgSetting.pkg = pkg;
11294 // REMOVE SharedUserSetting from method; update in a separate call.
11296 // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
11297 // secondaryCpuAbi are not known at this point so we always update them
11298 // to null here, only to reset them at a later point.
11299 Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting,
11300 destCodeFile, destResourceFile, pkg.applicationInfo.nativeLibraryDir,
11301 pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
11302 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
11303 pkg.getChildPackageNames(), UserManagerService.getInstance(),
11304 usesStaticLibraries, pkg.usesStaticLibrariesVersions);
11306 if (createNewPackage && originalPkgSetting != null) {
11307 // This is the initial transition from the original package, so,
11308 // fix up the new package's name now. We must do this after looking
11309 // up the package under its new name, so getPackageLP takes care of
11310 // fiddling things correctly.
11311 pkg.setPackageName(originalPkgSetting.name);
11313 // File a report about this.
11314 String msg = "New package " + pkgSetting.realName
11315 + " renamed to replace old package " + pkgSetting.name;
11316 reportSettingsProblem(Log.WARN, msg);
11319 final int userId = (user == null ? UserHandle.USER_SYSTEM : user.getIdentifier());
11320 // for existing packages, change the install state; but, only if it's explicitly specified
11321 if (!createNewPackage) {
11322 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
11323 final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
11324 setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
11326 // TODO(patb): see if we can do away with disabled check here.
11327 if (disabledPkgSetting != null
11328 || (0 != (scanFlags & SCAN_NEW_INSTALL)
11329 && pkgSetting != null && pkgSetting.isSystem())) {
11330 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
11333 // Apps which share a sharedUserId must be placed in the same selinux domain. If this
11334 // package is the first app installed as this shared user, set seInfoTargetSdkVersion to its
11335 // targetSdkVersion. These are later adjusted in PackageManagerService's constructor to be
11336 // the lowest targetSdkVersion of all apps within the shared user, which corresponds to the
11337 // least restrictive selinux domain.
11338 // NOTE: As new packages are installed / updated, the shared user's seinfoTargetSdkVersion
11339 // will NOT be modified until next boot, even if a lower targetSdkVersion is used. This
11340 // ensures that all packages continue to run in the same selinux domain.
11341 final int targetSdkVersion =
11342 ((sharedUserSetting != null) && (sharedUserSetting.packages.size() != 0)) ?
11343 sharedUserSetting.seInfoTargetSdkVersion : pkg.applicationInfo.targetSdkVersion;
11344 // TODO(b/71593002): isPrivileged for sharedUser and appInfo should never be out of sync.
11345 // They currently can be if the sharedUser apps are signed with the platform key.
11346 final boolean isPrivileged = (sharedUserSetting != null) ?
11347 sharedUserSetting.isPrivileged() | pkg.isPrivileged() : pkg.isPrivileged();
11349 pkg.applicationInfo.seInfo = SELinuxMMAC.getSeInfo(pkg, isPrivileged,
11350 pkg.applicationInfo.targetSandboxVersion, targetSdkVersion);
11351 pkg.applicationInfo.seInfoUser = SELinuxUtil.assignSeinfoUser(pkgSetting.readUserState(
11352 userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM : userId));
11354 pkg.mExtras = pkgSetting;
11355 pkg.applicationInfo.processName = fixProcessName(
11356 pkg.applicationInfo.packageName,
11357 pkg.applicationInfo.processName);
11359 if (!isPlatformPackage) {
11360 // Get all of our default paths setup
11361 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
11364 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
11366 if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
11367 if (needToDeriveAbi) {
11368 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
11369 final boolean extractNativeLibs = !pkg.isLibrary();
11370 derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
11371 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11373 // Some system apps still use directory structure for native libraries
11374 // in which case we might end up not detecting abi solely based on apk
11375 // structure. Try to detect abi based on directory structure.
11376 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
11377 pkg.applicationInfo.primaryCpuAbi == null) {
11378 setBundledAppAbisAndRoots(pkg, pkgSetting);
11379 setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11382 // This is not a first boot or an upgrade, don't bother deriving the
11383 // ABI during the scan. Instead, trust the value that was stored in the
11384 // package setting.
11385 pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
11386 pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
11388 setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11390 if (DEBUG_ABI_SELECTION) {
11391 Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
11392 pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
11393 pkg.applicationInfo.secondaryCpuAbi);
11397 if ((scanFlags & SCAN_MOVE) != 0) {
11398 // We haven't run dex-opt for this move (since we've moved the compiled output too)
11399 // but we already have this packages package info in the PackageSetting. We just
11400 // use that and derive the native library path based on the new codepath.
11401 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
11402 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
11405 // Set native library paths again. For moves, the path will be updated based on the
11406 // ABIs we've determined above. For non-moves, the path will be updated based on the
11407 // ABIs we determined during compilation, but the path will depend on the final
11408 // package path (after the rename away from the stage path).
11409 setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11412 // This is a special case for the "system" package, where the ABI is
11413 // dictated by the zygote configuration (and init.rc). We should keep track
11414 // of this ABI so that we can deal with "normal" applications that run under
11415 // the same UID correctly.
11416 if (isPlatformPackage) {
11417 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
11418 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
11421 // If there's a mismatch between the abi-override in the package setting
11422 // and the abiOverride specified for the install. Warn about this because we
11423 // would've already compiled the app without taking the package setting into
11425 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
11426 if (cpuAbiOverride == null && pkg.packageName != null) {
11427 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
11428 " for package " + pkg.packageName);
11432 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11433 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11434 pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
11436 // Copy the derived override back to the parsed package, so that we can
11437 // update the package settings accordingly.
11438 pkg.cpuAbiOverride = cpuAbiOverride;
11440 if (DEBUG_ABI_SELECTION) {
11441 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.packageName
11442 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
11443 + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
11446 // Push the derived path down into PackageSettings so we know what to
11447 // clean up at uninstall time.
11448 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
11450 if (DEBUG_ABI_SELECTION) {
11451 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
11452 " primary=" + pkg.applicationInfo.primaryCpuAbi +
11453 " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
11456 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
11457 // We don't do this here during boot because we can do it all
11458 // at once after scanning all existing packages.
11460 // We also do this *before* we perform dexopt on this package, so that
11461 // we can avoid redundant dexopts, and also to make sure we've got the
11462 // code and package path correct.
11463 changedAbiCodePath =
11464 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
11467 if (isUnderFactoryTest && pkg.requestedPermissions.contains(
11468 android.Manifest.permission.FACTORY_TEST)) {
11469 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
11472 if (isSystemApp(pkg)) {
11473 pkgSetting.isOrphaned = true;
11476 // Take care of first install / last update times.
11477 final long scanFileTime = getLastModifiedTime(pkg);
11478 if (currentTime != 0) {
11479 if (pkgSetting.firstInstallTime == 0) {
11480 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
11481 } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
11482 pkgSetting.lastUpdateTime = currentTime;
11484 } else if (pkgSetting.firstInstallTime == 0) {
11485 // We need *something*. Take time time stamp of the file.
11486 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
11487 } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
11488 if (scanFileTime != pkgSetting.timeStamp) {
11489 // A package on the system image has changed; consider this
11490 // to be an update.
11491 pkgSetting.lastUpdateTime = scanFileTime;
11494 pkgSetting.setTimeStamp(scanFileTime);
11496 pkgSetting.pkg = pkg;
11497 pkgSetting.pkgFlags = pkg.applicationInfo.flags;
11498 if (pkg.getLongVersionCode() != pkgSetting.versionCode) {
11499 pkgSetting.versionCode = pkg.getLongVersionCode();
11501 // Update volume if needed
11502 final String volumeUuid = pkg.applicationInfo.volumeUuid;
11503 if (!Objects.equals(volumeUuid, pkgSetting.volumeUuid)) {
11504 Slog.i(PackageManagerService.TAG,
11505 "Update" + (pkgSetting.isSystem() ? " system" : "")
11506 + " package " + pkg.packageName
11507 + " volume from " + pkgSetting.volumeUuid
11508 + " to " + volumeUuid);
11509 pkgSetting.volumeUuid = volumeUuid;
11512 SharedLibraryInfo staticSharedLibraryInfo = null;
11513 if (!TextUtils.isEmpty(pkg.staticSharedLibName)) {
11514 staticSharedLibraryInfo = SharedLibraryInfo.createForStatic(pkg);
11516 List<SharedLibraryInfo> dynamicSharedLibraryInfos = null;
11517 if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
11518 dynamicSharedLibraryInfos = new ArrayList<>(pkg.libraryNames.size());
11519 for (String name : pkg.libraryNames) {
11520 dynamicSharedLibraryInfos.add(SharedLibraryInfo.createForDynamic(pkg, name));
11524 return new ScanResult(request, true, pkgSetting, changedAbiCodePath,
11525 !createNewPackage /* existingSettingCopied */, staticSharedLibraryInfo,
11526 dynamicSharedLibraryInfos);
11530 * Returns {@code true} if the given file contains code. Otherwise {@code false}.
11532 private static boolean apkHasCode(String fileName) {
11533 StrictJarFile jarFile = null;
11535 jarFile = new StrictJarFile(fileName,
11536 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
11537 return jarFile.findEntry("classes.dex") != null;
11538 } catch (IOException ignore) {
11541 if (jarFile != null) {
11544 } catch (IOException ignore) {}
11550 * Enforces code policy for the package. This ensures that if an APK has
11551 * declared hasCode="true" in its manifest that the APK actually contains
11554 * @throws PackageManagerException If bytecode could not be found when it should exist
11556 private static void assertCodePolicy(PackageParser.Package pkg)
11557 throws PackageManagerException {
11558 final boolean shouldHaveCode =
11559 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
11560 if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
11561 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
11562 "Package " + pkg.baseCodePath + " code is missing");
11565 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
11566 for (int i = 0; i < pkg.splitCodePaths.length; i++) {
11567 final boolean splitShouldHaveCode =
11568 (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
11569 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
11570 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
11571 "Package " + pkg.splitCodePaths[i] + " code is missing");
11578 * Applies policy to the parsed package based upon the given policy flags.
11579 * Ensures the package is in a good state.
11581 * Implementation detail: This method must NOT have any side effect. It would
11582 * ideally be static, but, it requires locks to read system state.
11584 private static void applyPolicy(PackageParser.Package pkg, final @ParseFlags int parseFlags,
11585 final @ScanFlags int scanFlags, PackageParser.Package platformPkg) {
11586 if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
11587 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
11588 if (pkg.applicationInfo.isDirectBootAware()) {
11589 // we're direct boot aware; set for all components
11590 for (PackageParser.Service s : pkg.services) {
11591 s.info.encryptionAware = s.info.directBootAware = true;
11593 for (PackageParser.Provider p : pkg.providers) {
11594 p.info.encryptionAware = p.info.directBootAware = true;
11596 for (PackageParser.Activity a : pkg.activities) {
11597 a.info.encryptionAware = a.info.directBootAware = true;
11599 for (PackageParser.Activity r : pkg.receivers) {
11600 r.info.encryptionAware = r.info.directBootAware = true;
11603 if (compressedFileExists(pkg.codePath)) {
11607 // non system apps can't be flagged as core
11608 pkg.coreApp = false;
11609 // clear flags not applicable to regular apps
11610 pkg.applicationInfo.flags &=
11611 ~ApplicationInfo.FLAG_PERSISTENT;
11612 pkg.applicationInfo.privateFlags &=
11613 ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
11614 pkg.applicationInfo.privateFlags &=
11615 ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
11616 // cap permission priorities
11617 if (pkg.permissionGroups != null && pkg.permissionGroups.size() > 0) {
11618 for (int i = pkg.permissionGroups.size() - 1; i >= 0; --i) {
11619 pkg.permissionGroups.get(i).info.priority = 0;
11623 if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
11624 // clear protected broadcasts
11625 pkg.protectedBroadcasts = null;
11626 // ignore export request for single user receivers
11627 if (pkg.receivers != null) {
11628 for (int i = pkg.receivers.size() - 1; i >= 0; --i) {
11629 final PackageParser.Activity receiver = pkg.receivers.get(i);
11630 if ((receiver.info.flags & ActivityInfo.FLAG_SINGLE_USER) != 0) {
11631 receiver.info.exported = false;
11635 // ignore export request for single user services
11636 if (pkg.services != null) {
11637 for (int i = pkg.services.size() - 1; i >= 0; --i) {
11638 final PackageParser.Service service = pkg.services.get(i);
11639 if ((service.info.flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
11640 service.info.exported = false;
11644 // ignore export request for single user providers
11645 if (pkg.providers != null) {
11646 for (int i = pkg.providers.size() - 1; i >= 0; --i) {
11647 final PackageParser.Provider provider = pkg.providers.get(i);
11648 if ((provider.info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0) {
11649 provider.info.exported = false;
11655 if ((scanFlags & SCAN_AS_PRIVILEGED) != 0) {
11656 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
11659 if ((scanFlags & SCAN_AS_OEM) != 0) {
11660 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM;
11663 if ((scanFlags & SCAN_AS_VENDOR) != 0) {
11664 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_VENDOR;
11667 if ((scanFlags & SCAN_AS_PRODUCT) != 0) {
11668 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT;
11671 if ((scanFlags & SCAN_AS_PRODUCT_SERVICES) != 0) {
11672 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES;
11675 if ((scanFlags & SCAN_AS_ODM) != 0) {
11676 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ODM;
11679 // Check if the package is signed with the same key as the platform package.
11680 if (PLATFORM_PACKAGE_NAME.equals(pkg.packageName) ||
11681 (platformPkg != null && compareSignatures(
11682 platformPkg.mSigningDetails.signatures,
11683 pkg.mSigningDetails.signatures) == PackageManager.SIGNATURE_MATCH)) {
11684 pkg.applicationInfo.privateFlags |=
11685 ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY;
11688 if (!isSystemApp(pkg)) {
11689 // Only system apps can use these features.
11690 pkg.mOriginalPackages = null;
11691 pkg.mRealPackage = null;
11692 pkg.mAdoptPermissions = null;
11695 PackageBackwardCompatibility.modifySharedLibraries(pkg);
11698 private static @NonNull <T> T assertNotNull(@Nullable T object, String message)
11699 throws PackageManagerException {
11700 if (object == null) {
11701 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, message);
11707 * Asserts the parsed package is valid according to the given policy. If the
11708 * package is invalid, for whatever reason, throws {@link PackageManagerException}.
11710 * Implementation detail: This method must NOT have any side effects. It would
11711 * ideally be static, but, it requires locks to read system state.
11713 * @throws PackageManagerException If the package fails any of the validation checks
11715 private void assertPackageIsValid(PackageParser.Package pkg, final @ParseFlags int parseFlags,
11716 final @ScanFlags int scanFlags)
11717 throws PackageManagerException {
11718 if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
11719 assertCodePolicy(pkg);
11722 if (pkg.applicationInfo.getCodePath() == null ||
11723 pkg.applicationInfo.getResourcePath() == null) {
11724 // Bail out. The resource and code paths haven't been set.
11725 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
11726 "Code and resource paths haven't been set correctly");
11729 // Check that there is an APEX package with the same name only during install/first boot
11731 final boolean isUserInstall = (scanFlags & SCAN_BOOTING) == 0;
11732 final boolean isFirstBootOrUpgrade = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
11733 if ((isUserInstall || isFirstBootOrUpgrade)
11734 && mApexManager.isApexPackage(pkg.packageName)) {
11735 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11736 pkg.packageName + " is an APEX package and can't be installed as an APK.");
11739 // Make sure we're not adding any bogus keyset info
11740 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
11741 ksms.assertScannedPackageValid(pkg);
11743 synchronized (mPackages) {
11744 // The special "android" package can only be defined once
11745 if (pkg.packageName.equals("android")) {
11746 if (mAndroidApplication != null) {
11747 Slog.w(TAG, "*************************************************");
11748 Slog.w(TAG, "Core android package being redefined. Skipping.");
11749 Slog.w(TAG, " codePath=" + pkg.codePath);
11750 Slog.w(TAG, "*************************************************");
11751 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11752 "Core android package being redefined. Skipping.");
11756 // A package name must be unique; don't allow duplicates
11757 if ((scanFlags & SCAN_NEW_INSTALL) == 0 && mPackages.containsKey(pkg.packageName)) {
11758 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11759 "Application package " + pkg.packageName
11760 + " already installed. Skipping duplicate.");
11763 if (pkg.applicationInfo.isStaticSharedLibrary()) {
11764 // Static libs have a synthetic package name containing the version
11765 // but we still want the base name to be unique.
11766 if ((scanFlags & SCAN_NEW_INSTALL) == 0
11767 && mPackages.containsKey(pkg.manifestPackageName)) {
11768 throw new PackageManagerException(
11769 "Duplicate static shared lib provider package");
11772 // Static shared libraries should have at least O target SDK
11773 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
11774 throw new PackageManagerException(
11775 "Packages declaring static-shared libs must target O SDK or higher");
11778 // Package declaring static a shared lib cannot be instant apps
11779 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11780 throw new PackageManagerException(
11781 "Packages declaring static-shared libs cannot be instant apps");
11784 // Package declaring static a shared lib cannot be renamed since the package
11785 // name is synthetic and apps can't code around package manager internals.
11786 if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
11787 throw new PackageManagerException(
11788 "Packages declaring static-shared libs cannot be renamed");
11791 // Package declaring static a shared lib cannot declare child packages
11792 if (!ArrayUtils.isEmpty(pkg.childPackages)) {
11793 throw new PackageManagerException(
11794 "Packages declaring static-shared libs cannot have child packages");
11797 // Package declaring static a shared lib cannot declare dynamic libs
11798 if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
11799 throw new PackageManagerException(
11800 "Packages declaring static-shared libs cannot declare dynamic libs");
11803 // Package declaring static a shared lib cannot declare shared users
11804 if (pkg.mSharedUserId != null) {
11805 throw new PackageManagerException(
11806 "Packages declaring static-shared libs cannot declare shared users");
11809 // Static shared libs cannot declare activities
11810 if (!pkg.activities.isEmpty()) {
11811 throw new PackageManagerException(
11812 "Static shared libs cannot declare activities");
11815 // Static shared libs cannot declare services
11816 if (!pkg.services.isEmpty()) {
11817 throw new PackageManagerException(
11818 "Static shared libs cannot declare services");
11821 // Static shared libs cannot declare providers
11822 if (!pkg.providers.isEmpty()) {
11823 throw new PackageManagerException(
11824 "Static shared libs cannot declare content providers");
11827 // Static shared libs cannot declare receivers
11828 if (!pkg.receivers.isEmpty()) {
11829 throw new PackageManagerException(
11830 "Static shared libs cannot declare broadcast receivers");
11833 // Static shared libs cannot declare permission groups
11834 if (!pkg.permissionGroups.isEmpty()) {
11835 throw new PackageManagerException(
11836 "Static shared libs cannot declare permission groups");
11839 // Static shared libs cannot declare permissions
11840 if (!pkg.permissions.isEmpty()) {
11841 throw new PackageManagerException(
11842 "Static shared libs cannot declare permissions");
11845 // Static shared libs cannot declare protected broadcasts
11846 if (pkg.protectedBroadcasts != null) {
11847 throw new PackageManagerException(
11848 "Static shared libs cannot declare protected broadcasts");
11851 // Static shared libs cannot be overlay targets
11852 if (pkg.mOverlayTarget != null) {
11853 throw new PackageManagerException(
11854 "Static shared libs cannot be overlay targets");
11857 // The version codes must be ordered as lib versions
11858 long minVersionCode = Long.MIN_VALUE;
11859 long maxVersionCode = Long.MAX_VALUE;
11861 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(
11862 pkg.staticSharedLibName);
11863 if (versionedLib != null) {
11864 final int versionCount = versionedLib.size();
11865 for (int i = 0; i < versionCount; i++) {
11866 SharedLibraryInfo libInfo = versionedLib.valueAt(i);
11867 final long libVersionCode = libInfo.getDeclaringPackage()
11868 .getLongVersionCode();
11869 if (libInfo.getLongVersion() < pkg.staticSharedLibVersion) {
11870 minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
11871 } else if (libInfo.getLongVersion() > pkg.staticSharedLibVersion) {
11872 maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
11874 minVersionCode = maxVersionCode = libVersionCode;
11879 if (pkg.getLongVersionCode() < minVersionCode
11880 || pkg.getLongVersionCode() > maxVersionCode) {
11881 throw new PackageManagerException("Static shared"
11882 + " lib version codes must be ordered as lib versions");
11886 // Only privileged apps and updated privileged apps can add child packages.
11887 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
11888 if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
11889 throw new PackageManagerException("Only privileged apps can add child "
11890 + "packages. Ignoring package " + pkg.packageName);
11892 final int childCount = pkg.childPackages.size();
11893 for (int i = 0; i < childCount; i++) {
11894 PackageParser.Package childPkg = pkg.childPackages.get(i);
11895 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
11896 childPkg.packageName)) {
11897 throw new PackageManagerException("Can't override child of "
11898 + "another disabled app. Ignoring package " + pkg.packageName);
11903 // If we're only installing presumed-existing packages, require that the
11904 // scanned APK is both already known and at the path previously established
11905 // for it. Previously unknown packages we pick up normally, but if we have an
11906 // a priori expectation about this package's install presence, enforce it.
11907 // With a singular exception for new system packages. When an OTA contains
11908 // a new system package, we allow the codepath to change from a system location
11909 // to the user-installed location. If we don't allow this change, any newer,
11910 // user-installed version of the application will be ignored.
11911 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
11912 if (mExpectingBetter.containsKey(pkg.packageName)) {
11913 logCriticalInfo(Log.WARN,
11914 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
11916 PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
11917 if (known != null) {
11918 if (DEBUG_PACKAGE_SCANNING) {
11919 Log.d(TAG, "Examining " + pkg.codePath
11920 + " and requiring known paths " + known.codePathString
11921 + " & " + known.resourcePathString);
11923 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
11924 || !pkg.applicationInfo.getResourcePath().equals(
11925 known.resourcePathString)) {
11926 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
11927 "Application package " + pkg.packageName
11928 + " found at " + pkg.applicationInfo.getCodePath()
11929 + " but expected at " + known.codePathString
11933 throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
11934 "Application package " + pkg.packageName
11935 + " not found; ignoring.");
11940 // Verify that this new package doesn't have any content providers
11941 // that conflict with existing packages. Only do this if the
11942 // package isn't already installed, since we don't want to break
11943 // things that are installed.
11944 if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
11945 mComponentResolver.assertProvidersNotDefined(pkg);
11948 // Verify that packages sharing a user with a privileged app are marked as privileged.
11949 if (!pkg.isPrivileged() && (pkg.mSharedUserId != null)) {
11950 SharedUserSetting sharedUserSetting = null;
11952 sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false);
11953 } catch (PackageManagerException ignore) {}
11954 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
11955 // Exempt SharedUsers signed with the platform key.
11956 PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
11957 if ((platformPkgSetting.signatures.mSigningDetails
11958 != PackageParser.SigningDetails.UNKNOWN)
11959 && (compareSignatures(
11960 platformPkgSetting.signatures.mSigningDetails.signatures,
11961 pkg.mSigningDetails.signatures)
11962 != PackageManager.SIGNATURE_MATCH)) {
11963 throw new PackageManagerException("Apps that share a user with a " +
11964 "privileged app must themselves be marked as privileged. " +
11965 pkg.packageName + " shares privileged user " +
11966 pkg.mSharedUserId + ".");
11971 // Apply policies specific for runtime resource overlays (RROs).
11972 if (pkg.mOverlayTarget != null) {
11973 // System overlays have some restrictions on their use of the 'static' state.
11974 if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
11975 // We are scanning a system overlay. This can be the first scan of the
11976 // system/vendor/oem partition, or an update to the system overlay.
11977 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11978 // This must be an update to a system overlay.
11979 final PackageSetting previousPkg = assertNotNull(
11980 mSettings.getPackageLPr(pkg.packageName),
11981 "previous package state not present");
11983 // previousPkg.pkg may be null: the package will be not be scanned if the
11984 // package manager knows there is a newer version on /data.
11985 // TODO[b/79435695]: Find a better way to keep track of the "static"
11986 // property for RROs instead of having to parse packages on /system
11987 PackageParser.Package ppkg = previousPkg.pkg;
11988 if (ppkg == null) {
11990 final PackageParser pp = new PackageParser();
11991 ppkg = pp.parsePackage(previousPkg.codePath,
11992 parseFlags | PackageParser.PARSE_IS_SYSTEM_DIR);
11993 } catch (PackageParserException e) {
11994 Slog.w(TAG, "failed to parse " + previousPkg.codePath, e);
11998 // Static overlays cannot be updated.
11999 if (ppkg != null && ppkg.mOverlayIsStatic) {
12000 throw new PackageManagerException("Overlay " + pkg.packageName +
12001 " is static and cannot be upgraded.");
12002 // Non-static overlays cannot be converted to static overlays.
12003 } else if (pkg.mOverlayIsStatic) {
12004 throw new PackageManagerException("Overlay " + pkg.packageName +
12005 " cannot be upgraded into a static overlay.");
12009 // The overlay is a non-system overlay. Non-system overlays cannot be static.
12010 if (pkg.mOverlayIsStatic) {
12011 throw new PackageManagerException("Overlay " + pkg.packageName +
12012 " is static but not pre-installed.");
12015 // A non-preloaded overlay packages must have targetSdkVersion >= Q, or be
12016 // signed with the platform certificate. Check this in increasing order of
12017 // computational cost.
12018 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.Q) {
12019 final PackageSetting platformPkgSetting =
12020 mSettings.getPackageLPr("android");
12021 if ((platformPkgSetting.signatures.mSigningDetails
12022 != PackageParser.SigningDetails.UNKNOWN)
12023 && (compareSignatures(
12024 platformPkgSetting.signatures.mSigningDetails.signatures,
12025 pkg.mSigningDetails.signatures)
12026 != PackageManager.SIGNATURE_MATCH)) {
12027 throw new PackageManagerException("Overlay " + pkg.packageName
12028 + " must target Q or later, "
12029 + "or be signed with the platform certificate");
12033 // A non-preloaded overlay package, without <overlay android:targetName>, will
12034 // only be used if it is signed with the same certificate as its target. If the
12035 // target is already installed, check this here to augment the last line of
12036 // defence which is OMS.
12037 if (pkg.mOverlayTargetName == null) {
12038 final PackageSetting targetPkgSetting =
12039 mSettings.getPackageLPr(pkg.mOverlayTarget);
12040 if (targetPkgSetting != null) {
12041 if ((targetPkgSetting.signatures.mSigningDetails
12042 != PackageParser.SigningDetails.UNKNOWN)
12043 && (compareSignatures(
12044 targetPkgSetting.signatures.mSigningDetails.signatures,
12045 pkg.mSigningDetails.signatures)
12046 != PackageManager.SIGNATURE_MATCH)) {
12047 throw new PackageManagerException("Overlay " + pkg.packageName
12048 + " and target " + pkg.mOverlayTarget + " signed with"
12049 + " different certificates, and the overlay lacks"
12050 + " <overlay android:targetName>");
12059 @GuardedBy("mPackages")
12060 private boolean addBuiltInSharedLibraryLocked(String path, String name) {
12061 if (nonStaticSharedLibExistsLocked(name)) {
12065 SharedLibraryInfo libraryInfo = new SharedLibraryInfo(path, null, null, name,
12066 (long) SharedLibraryInfo.VERSION_UNDEFINED, SharedLibraryInfo.TYPE_BUILTIN,
12067 new VersionedPackage(PLATFORM_PACKAGE_NAME, (long) 0),
12070 commitSharedLibraryInfoLocked(libraryInfo);
12074 @GuardedBy("mPackages")
12075 private boolean nonStaticSharedLibExistsLocked(String name) {
12076 return sharedLibExists(name, SharedLibraryInfo.VERSION_UNDEFINED, mSharedLibraries);
12079 private static boolean sharedLibExists(final String name, final long version,
12080 Map<String, LongSparseArray<SharedLibraryInfo>> librarySource) {
12081 LongSparseArray<SharedLibraryInfo> versionedLib = librarySource.get(name);
12082 if (versionedLib != null && versionedLib.indexOfKey(version) >= 0) {
12088 @GuardedBy("mPackages")
12089 private void commitSharedLibraryInfoLocked(SharedLibraryInfo libraryInfo) {
12090 final String name = libraryInfo.getName();
12091 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(name);
12092 if (versionedLib == null) {
12093 versionedLib = new LongSparseArray<>();
12094 mSharedLibraries.put(name, versionedLib);
12096 final String declaringPackageName = libraryInfo.getDeclaringPackage().getPackageName();
12097 if (libraryInfo.getType() == SharedLibraryInfo.TYPE_STATIC) {
12098 mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
12100 versionedLib.put(libraryInfo.getLongVersion(), libraryInfo);
12103 private boolean removeSharedLibraryLPw(String name, long version) {
12104 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(name);
12105 if (versionedLib == null) {
12108 final int libIdx = versionedLib.indexOfKey(version);
12112 SharedLibraryInfo libraryInfo = versionedLib.valueAt(libIdx);
12113 versionedLib.remove(version);
12114 if (versionedLib.size() <= 0) {
12115 mSharedLibraries.remove(name);
12116 if (libraryInfo.getType() == SharedLibraryInfo.TYPE_STATIC) {
12117 mStaticLibsByDeclaringPackage.remove(libraryInfo.getDeclaringPackage()
12118 .getPackageName());
12125 * Adds a scanned package to the system. When this method is finished, the package will
12126 * be available for query, resolution, etc...
12128 private void commitPackageSettings(PackageParser.Package pkg,
12129 @Nullable PackageParser.Package oldPkg, PackageSetting pkgSetting,
12130 final @ScanFlags int scanFlags, boolean chatty, ReconciledPackage reconciledPkg) {
12131 final String pkgName = pkg.packageName;
12132 if (mCustomResolverComponentName != null &&
12133 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
12134 setUpCustomResolverActivity(pkg);
12137 if (pkg.packageName.equals("android")) {
12138 synchronized (mPackages) {
12139 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
12140 // Set up information for our fall-back user intent resolution activity.
12141 mPlatformPackage = pkg;
12142 pkg.mVersionCode = mSdkVersion;
12143 pkg.mVersionCodeMajor = 0;
12144 mAndroidApplication = pkg.applicationInfo;
12145 if (!mResolverReplaced) {
12146 mResolveActivity.applicationInfo = mAndroidApplication;
12147 mResolveActivity.name = ResolverActivity.class.getName();
12148 mResolveActivity.packageName = mAndroidApplication.packageName;
12149 mResolveActivity.processName = "system:ui";
12150 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
12151 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
12152 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
12153 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
12154 mResolveActivity.exported = true;
12155 mResolveActivity.enabled = true;
12156 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
12157 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
12158 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
12159 | ActivityInfo.CONFIG_SCREEN_LAYOUT
12160 | ActivityInfo.CONFIG_ORIENTATION
12161 | ActivityInfo.CONFIG_KEYBOARD
12162 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
12163 mResolveInfo.activityInfo = mResolveActivity;
12164 mResolveInfo.priority = 0;
12165 mResolveInfo.preferredOrder = 0;
12166 mResolveInfo.match = 0;
12167 mResolveComponentName = new ComponentName(
12168 mAndroidApplication.packageName, mResolveActivity.name);
12174 ArrayList<PackageParser.Package> clientLibPkgs = null;
12176 synchronized (mPackages) {
12177 if (!ArrayUtils.isEmpty(reconciledPkg.allowedSharedLibraryInfos)) {
12178 for (SharedLibraryInfo info : reconciledPkg.allowedSharedLibraryInfos) {
12179 commitSharedLibraryInfoLocked(info);
12181 final Map<String, PackageParser.Package> combinedPackages =
12182 reconciledPkg.getCombinedPackages();
12184 // Shared libraries for the package need to be updated.
12185 updateSharedLibrariesLocked(pkg, null, combinedPackages);
12186 } catch (PackageManagerException e) {
12187 Slog.e(TAG, "updateSharedLibrariesLPr failed: ", e);
12189 // Update all applications that use this library. Skip when booting
12190 // since this will be done after all packages are scaned.
12191 if ((scanFlags & SCAN_BOOTING) == 0) {
12192 clientLibPkgs = updateAllSharedLibrariesLocked(pkg, combinedPackages);
12197 if ((scanFlags & SCAN_BOOTING) != 0) {
12198 // No apps can run during boot scan, so they don't need to be frozen
12199 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
12200 // Caller asked to not kill app, so it's probably not frozen
12201 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
12202 // Caller asked us to ignore frozen check for some reason; they
12203 // probably didn't know the package name
12205 // We're doing major surgery on this package, so it better be frozen
12206 // right now to keep it from launching
12207 checkPackageFrozen(pkgName);
12210 // Also need to kill any apps that are dependent on the library.
12211 if (clientLibPkgs != null) {
12212 for (int i=0; i<clientLibPkgs.size(); i++) {
12213 PackageParser.Package clientPkg = clientLibPkgs.get(i);
12214 killApplication(clientPkg.applicationInfo.packageName,
12215 clientPkg.applicationInfo.uid, "update lib");
12220 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
12222 synchronized (mPackages) {
12223 // We don't expect installation to fail beyond this point
12225 // Add the new setting to mSettings
12226 mSettings.insertPackageSettingLPw(pkgSetting, pkg);
12227 // Add the new setting to mPackages
12228 mPackages.put(pkg.applicationInfo.packageName, pkg);
12230 // Add the package's KeySets to the global KeySetManagerService
12231 KeySetManagerService ksms = mSettings.mKeySetManagerService;
12232 ksms.addScannedPackageLPw(pkg);
12234 mComponentResolver.addAllComponents(pkg, chatty);
12236 // Don't allow ephemeral applications to define new permissions groups.
12237 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
12238 Slog.w(TAG, "Permission groups from package " + pkg.packageName
12239 + " ignored: instant apps cannot define new permission groups.");
12241 mPermissionManager.addAllPermissionGroups(pkg, chatty);
12244 // Don't allow ephemeral applications to define new permissions.
12245 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
12246 Slog.w(TAG, "Permissions from package " + pkg.packageName
12247 + " ignored: instant apps cannot define new permissions.");
12249 mPermissionManager.addAllPermissions(pkg, chatty);
12252 int collectionSize = pkg.instrumentation.size();
12253 StringBuilder r = null;
12255 for (i = 0; i < collectionSize; i++) {
12256 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12257 a.info.packageName = pkg.applicationInfo.packageName;
12258 a.info.sourceDir = pkg.applicationInfo.sourceDir;
12259 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
12260 a.info.splitNames = pkg.splitNames;
12261 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
12262 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
12263 a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
12264 a.info.dataDir = pkg.applicationInfo.dataDir;
12265 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
12266 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
12267 a.info.primaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
12268 a.info.secondaryCpuAbi = pkg.applicationInfo.secondaryCpuAbi;
12269 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
12270 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
12271 mInstrumentation.put(a.getComponentName(), a);
12274 r = new StringBuilder(256);
12278 r.append(a.info.name);
12282 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r);
12285 if (pkg.protectedBroadcasts != null) {
12286 collectionSize = pkg.protectedBroadcasts.size();
12287 synchronized (mProtectedBroadcasts) {
12288 for (i = 0; i < collectionSize; i++) {
12289 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
12294 if (oldPkg != null) {
12295 // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
12296 // revoke callbacks from this method might need to kill apps which need the
12297 // mPackages lock on a different thread. This would dead lock.
12299 // Hence create a copy of all package names and pass it into
12300 // revokeRuntimePermissionsIfGroupChanged. Only for those permissions might get
12301 // revoked. If a new package is added before the async code runs the permission
12302 // won't be granted yet, hence new packages are no problem.
12303 final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
12305 AsyncTask.execute(() ->
12306 mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg,
12307 allPackageNames, mPermissionCallback));
12311 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12315 * Derive the ABI of a non-system package located at {@code scanFile}. This information
12316 * is derived purely on the basis of the contents of {@code scanFile} and
12317 * {@code cpuAbiOverride}.
12319 * If {@code extractLibs} is true, native libraries are extracted from the app if required.
12321 private static void derivePackageAbi(PackageParser.Package pkg, String cpuAbiOverride,
12322 boolean extractLibs)
12323 throws PackageManagerException {
12324 // Give ourselves some initial paths; we'll come back for another
12325 // pass once we've determined ABI below.
12326 setNativeLibraryPaths(pkg, sAppLib32InstallDir);
12328 // We shouldn't attempt to extract libs from system app when it was not updated.
12329 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
12330 extractLibs = false;
12333 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
12334 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
12336 NativeLibraryHelper.Handle handle = null;
12338 handle = NativeLibraryHelper.Handle.create(pkg);
12339 // TODO(multiArch): This can be null for apps that didn't go through the
12340 // usual installation process. We can calculate it again, like we
12341 // do during install time.
12343 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
12345 final File nativeLibraryRoot = new File(nativeLibraryRootStr);
12347 // Null out the abis so that they can be recalculated.
12348 pkg.applicationInfo.primaryCpuAbi = null;
12349 pkg.applicationInfo.secondaryCpuAbi = null;
12350 if (isMultiArch(pkg.applicationInfo)) {
12351 // Warn if we've set an abiOverride for multi-lib packages..
12352 // By definition, we need to copy both 32 and 64 bit libraries for
12354 if (pkg.cpuAbiOverride != null
12355 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
12356 Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
12359 int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
12360 int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
12361 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
12363 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
12364 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
12365 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
12366 useIsaSpecificSubdirs);
12368 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
12369 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
12371 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12374 // Shared library native code should be in the APK zip aligned
12375 if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
12376 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12377 "Shared library native lib extraction not supported");
12380 maybeThrowExceptionForMultiArchCopy(
12381 "Error unpackaging 32 bit native libs for multiarch app.", abi32);
12383 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
12385 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
12386 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
12387 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
12388 useIsaSpecificSubdirs);
12390 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
12391 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
12393 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12396 maybeThrowExceptionForMultiArchCopy(
12397 "Error unpackaging 64 bit native libs for multiarch app.", abi64);
12400 // Shared library native libs should be in the APK zip aligned
12401 if (extractLibs && pkg.isLibrary()) {
12402 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12403 "Shared library native lib extraction not supported");
12405 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
12409 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
12411 if (pkg.use32bitAbi) {
12412 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
12413 pkg.applicationInfo.primaryCpuAbi = abi;
12415 pkg.applicationInfo.secondaryCpuAbi = abi;
12418 pkg.applicationInfo.primaryCpuAbi = abi;
12422 String[] abiList = (cpuAbiOverride != null) ?
12423 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
12425 // Enable gross and lame hacks for apps that are built with old
12426 // SDK tools. We must scan their APKs for renderscript bitcode and
12427 // not launch them if it's present. Don't bother checking on devices
12428 // that don't have 64 bit support.
12429 boolean needsRenderScriptOverride = false;
12430 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
12431 NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
12432 abiList = Build.SUPPORTED_32_BIT_ABIS;
12433 needsRenderScriptOverride = true;
12438 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
12439 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
12440 nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
12442 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
12443 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
12445 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12447 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
12448 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12449 "Error unpackaging native libs for app, errorCode=" + copyRet);
12452 if (copyRet >= 0) {
12453 // Shared libraries that have native libs must be multi-architecture
12454 if (pkg.isLibrary()) {
12455 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12456 "Shared library with native libs must be multiarch");
12458 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
12459 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
12460 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
12461 } else if (needsRenderScriptOverride) {
12462 pkg.applicationInfo.primaryCpuAbi = abiList[0];
12465 } catch (IOException ioe) {
12466 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
12468 IoUtils.closeQuietly(handle);
12471 // Now that we've calculated the ABIs and determined if it's an internal app,
12472 // we will go ahead and populate the nativeLibraryPath.
12473 setNativeLibraryPaths(pkg, sAppLib32InstallDir);
12477 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
12478 * i.e, so that all packages can be run inside a single process if required.
12480 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
12481 * this function will either try and make the ABI for all packages in {@code packagesForUser}
12482 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
12483 * the ABI selected for {@code packagesForUser}. This variant is used when installing or
12484 * updating a package that belongs to a shared user.
12486 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
12487 * adds unnecessary complexity.
12489 private static @Nullable List<String> adjustCpuAbisForSharedUserLPw(
12490 Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) {
12491 List<String> changedAbiCodePath = null;
12492 String requiredInstructionSet = null;
12493 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
12494 requiredInstructionSet = VMRuntime.getInstructionSet(
12495 scannedPackage.applicationInfo.primaryCpuAbi);
12498 PackageSetting requirer = null;
12499 for (PackageSetting ps : packagesForUser) {
12500 // If packagesForUser contains scannedPackage, we skip it. This will happen
12501 // when scannedPackage is an update of an existing package. Without this check,
12502 // we will never be able to change the ABI of any package belonging to a shared
12503 // user, even if it's compatible with other packages.
12504 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
12505 if (ps.primaryCpuAbiString == null) {
12509 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
12510 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
12511 // We have a mismatch between instruction sets (say arm vs arm64) warn about
12512 // this but there's not much we can do.
12513 String errorMessage = "Instruction set mismatch, "
12514 + ((requirer == null) ? "[caller]" : requirer)
12515 + " requires " + requiredInstructionSet + " whereas " + ps
12516 + " requires " + instructionSet;
12517 Slog.w(TAG, errorMessage);
12520 if (requiredInstructionSet == null) {
12521 requiredInstructionSet = instructionSet;
12527 if (requiredInstructionSet != null) {
12528 String adjustedAbi;
12529 if (requirer != null) {
12530 // requirer != null implies that either scannedPackage was null or that scannedPackage
12531 // did not require an ABI, in which case we have to adjust scannedPackage to match
12532 // the ABI of the set (which is the same as requirer's ABI)
12533 adjustedAbi = requirer.primaryCpuAbiString;
12534 if (scannedPackage != null) {
12535 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
12538 // requirer == null implies that we're updating all ABIs in the set to
12539 // match scannedPackage.
12540 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi;
12543 for (PackageSetting ps : packagesForUser) {
12544 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
12545 if (ps.primaryCpuAbiString != null) {
12549 ps.primaryCpuAbiString = adjustedAbi;
12550 if (ps.pkg != null && ps.pkg.applicationInfo != null &&
12551 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
12552 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
12553 if (DEBUG_ABI_SELECTION) {
12554 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
12556 + (requirer != null ? requirer.pkg : "null")
12557 + ", scannedPackage="
12558 + (scannedPackage != null ? scannedPackage : "null")
12561 if (changedAbiCodePath == null) {
12562 changedAbiCodePath = new ArrayList<>();
12564 changedAbiCodePath.add(ps.codePathString);
12569 return changedAbiCodePath;
12572 private void setUpCustomResolverActivity(PackageParser.Package pkg) {
12573 synchronized (mPackages) {
12574 mResolverReplaced = true;
12575 // Set up information for custom user intent resolution activity.
12576 mResolveActivity.applicationInfo = pkg.applicationInfo;
12577 mResolveActivity.name = mCustomResolverComponentName.getClassName();
12578 mResolveActivity.packageName = pkg.applicationInfo.packageName;
12579 mResolveActivity.processName = pkg.applicationInfo.packageName;
12580 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
12581 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
12582 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12583 mResolveActivity.theme = 0;
12584 mResolveActivity.exported = true;
12585 mResolveActivity.enabled = true;
12586 mResolveInfo.activityInfo = mResolveActivity;
12587 mResolveInfo.priority = 0;
12588 mResolveInfo.preferredOrder = 0;
12589 mResolveInfo.match = 0;
12590 mResolveComponentName = mCustomResolverComponentName;
12591 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
12592 mResolveComponentName);
12596 private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
12597 if (installerActivity == null) {
12598 if (DEBUG_INSTANT) {
12599 Slog.d(TAG, "Clear ephemeral installer activity");
12601 mInstantAppInstallerActivity = null;
12605 if (DEBUG_INSTANT) {
12606 Slog.d(TAG, "Set ephemeral installer activity: "
12607 + installerActivity.getComponentName());
12609 // Set up information for ephemeral installer activity
12610 mInstantAppInstallerActivity = installerActivity;
12611 mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
12612 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12613 mInstantAppInstallerActivity.exported = true;
12614 mInstantAppInstallerActivity.enabled = true;
12615 mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
12616 mInstantAppInstallerInfo.priority = 1;
12617 mInstantAppInstallerInfo.preferredOrder = 1;
12618 mInstantAppInstallerInfo.isDefault = true;
12619 mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
12620 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
12623 private static String calculateBundledApkRoot(final String codePathString) {
12624 final File codePath = new File(codePathString);
12625 final File codeRoot;
12626 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
12627 codeRoot = Environment.getRootDirectory();
12628 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
12629 codeRoot = Environment.getOemDirectory();
12630 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
12631 codeRoot = Environment.getVendorDirectory();
12632 } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
12633 codeRoot = Environment.getOdmDirectory();
12634 } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) {
12635 codeRoot = Environment.getProductDirectory();
12636 } else if (FileUtils.contains(Environment.getProductServicesDirectory(), codePath)) {
12637 codeRoot = Environment.getProductServicesDirectory();
12638 } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
12639 codeRoot = Environment.getOdmDirectory();
12641 // Unrecognized code path; take its top real segment as the apk root:
12642 // e.g. /something/app/blah.apk => /something
12644 File f = codePath.getCanonicalFile();
12645 File parent = f.getParentFile(); // non-null because codePath is a file
12647 while ((tmp = parent.getParentFile()) != null) {
12652 Slog.w(TAG, "Unrecognized code path "
12653 + codePath + " - using " + codeRoot);
12654 } catch (IOException e) {
12655 // Can't canonicalize the code path -- shenanigans?
12656 Slog.w(TAG, "Can't canonicalize code path " + codePath);
12657 return Environment.getRootDirectory().getPath();
12660 return codeRoot.getPath();
12664 * Derive and set the location of native libraries for the given package,
12665 * which varies depending on where and how the package was installed.
12667 private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
12668 final ApplicationInfo info = pkg.applicationInfo;
12669 final String codePath = pkg.codePath;
12670 final File codeFile = new File(codePath);
12671 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
12673 info.nativeLibraryRootDir = null;
12674 info.nativeLibraryRootRequiresIsa = false;
12675 info.nativeLibraryDir = null;
12676 info.secondaryNativeLibraryDir = null;
12678 if (isApkFile(codeFile)) {
12679 // Monolithic install
12681 // If "/system/lib64/apkname" exists, assume that is the per-package
12682 // native library directory to use; otherwise use "/system/lib/apkname".
12683 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
12684 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
12685 getPrimaryInstructionSet(info));
12687 // This is a bundled system app so choose the path based on the ABI.
12688 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
12689 // is just the default path.
12690 final String apkName = deriveCodePathName(codePath);
12691 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
12692 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
12693 apkName).getAbsolutePath();
12695 if (info.secondaryCpuAbi != null) {
12696 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
12697 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
12698 secondaryLibDir, apkName).getAbsolutePath();
12701 final String apkName = deriveCodePathName(codePath);
12702 info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
12703 .getAbsolutePath();
12706 info.nativeLibraryRootRequiresIsa = false;
12707 info.nativeLibraryDir = info.nativeLibraryRootDir;
12710 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
12711 info.nativeLibraryRootRequiresIsa = true;
12713 info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
12714 getPrimaryInstructionSet(info)).getAbsolutePath();
12716 if (info.secondaryCpuAbi != null) {
12717 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
12718 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
12724 * Calculate the abis and roots for a bundled app. These can uniquely
12725 * be determined from the contents of the system partition, i.e whether
12726 * it contains 64 or 32 bit shared libraries etc. We do not validate any
12727 * of this information, and instead assume that the system was built
12730 private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
12731 PackageSetting pkgSetting) {
12732 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
12734 // If "/system/lib64/apkname" exists, assume that is the per-package
12735 // native library directory to use; otherwise use "/system/lib/apkname".
12736 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
12737 setBundledAppAbi(pkg, apkRoot, apkName);
12738 // pkgSetting might be null during rescan following uninstall of updates
12739 // to a bundled app, so accommodate that possibility. The settings in
12740 // that case will be established later from the parsed package.
12742 // If the settings aren't null, sync them up with what we've just derived.
12743 // note that apkRoot isn't stored in the package settings.
12744 if (pkgSetting != null) {
12745 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
12746 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
12751 * Deduces the ABI of a bundled app and sets the relevant fields on the
12752 * parsed pkg object.
12754 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
12755 * under which system libraries are installed.
12756 * @param apkName the name of the installed package.
12758 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
12759 final File codeFile = new File(pkg.codePath);
12761 final boolean has64BitLibs;
12762 final boolean has32BitLibs;
12763 if (isApkFile(codeFile)) {
12764 // Monolithic install
12765 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
12766 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
12769 final File rootDir = new File(codeFile, LIB_DIR_NAME);
12770 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
12771 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
12772 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
12773 has64BitLibs = (new File(rootDir, isa)).exists();
12775 has64BitLibs = false;
12777 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
12778 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
12779 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
12780 has32BitLibs = (new File(rootDir, isa)).exists();
12782 has32BitLibs = false;
12786 if (has64BitLibs && !has32BitLibs) {
12787 // The package has 64 bit libs, but not 32 bit libs. Its primary
12788 // ABI should be 64 bit. We can safely assume here that the bundled
12789 // native libraries correspond to the most preferred ABI in the list.
12791 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12792 pkg.applicationInfo.secondaryCpuAbi = null;
12793 } else if (has32BitLibs && !has64BitLibs) {
12794 // The package has 32 bit libs but not 64 bit libs. Its primary
12795 // ABI should be 32 bit.
12797 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12798 pkg.applicationInfo.secondaryCpuAbi = null;
12799 } else if (has32BitLibs && has64BitLibs) {
12800 // The application has both 64 and 32 bit bundled libraries. We check
12801 // here that the app declares multiArch support, and warn if it doesn't.
12803 // We will be lenient here and record both ABIs. The primary will be the
12804 // ABI that's higher on the list, i.e, a device that's configured to prefer
12805 // 64 bit apps will see a 64 bit primary ABI,
12807 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
12808 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
12811 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
12812 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12813 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12815 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12816 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12819 pkg.applicationInfo.primaryCpuAbi = null;
12820 pkg.applicationInfo.secondaryCpuAbi = null;
12824 private void killApplication(String pkgName, int appId, String reason) {
12825 killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
12828 private void killApplication(String pkgName, int appId, int userId, String reason) {
12829 // Request the ActivityManager to kill the process(only for existing packages)
12830 // so that we do not end up in a confused state while the user is still using the older
12831 // version of the application while the new one gets installed.
12832 final long token = Binder.clearCallingIdentity();
12834 IActivityManager am = ActivityManager.getService();
12837 am.killApplication(pkgName, appId, userId, reason);
12838 } catch (RemoteException e) {
12842 Binder.restoreCallingIdentity(token);
12846 private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
12847 // Remove the parent package setting
12848 PackageSetting ps = (PackageSetting) pkg.mExtras;
12850 removePackageLI(ps.name, chatty);
12851 } else if (DEBUG_REMOVE && chatty) {
12852 Log.d(TAG, "Not removing package " + pkg.packageName + "; mExtras == null");
12854 // Remove the child package setting
12855 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12856 for (int i = 0; i < childCount; i++) {
12857 PackageParser.Package childPkg = pkg.childPackages.get(i);
12858 ps = (PackageSetting) childPkg.mExtras;
12860 removePackageLI(ps.name, chatty);
12865 void removePackageLI(String packageName, boolean chatty) {
12866 if (DEBUG_INSTALL) {
12868 Log.d(TAG, "Removing package " + packageName);
12872 synchronized (mPackages) {
12873 final PackageParser.Package removedPackage = mPackages.remove(packageName);
12874 if (removedPackage != null) {
12875 cleanPackageDataStructuresLILPw(removedPackage, chatty);
12880 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
12881 if (DEBUG_INSTALL) {
12883 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
12887 synchronized (mPackages) {
12888 // Remove the parent package
12889 mPackages.remove(pkg.applicationInfo.packageName);
12890 cleanPackageDataStructuresLILPw(pkg, chatty);
12892 // Remove the child packages
12893 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12894 for (int i = 0; i < childCount; i++) {
12895 PackageParser.Package childPkg = pkg.childPackages.get(i);
12896 mPackages.remove(childPkg.applicationInfo.packageName);
12897 cleanPackageDataStructuresLILPw(childPkg, chatty);
12902 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
12903 mComponentResolver.removeAllComponents(pkg, chatty);
12905 mPermissionManager.removeAllPermissions(pkg, chatty);
12907 final int instrumentationSize = pkg.instrumentation.size();
12908 StringBuilder r = null;
12910 for (i = 0; i < instrumentationSize; i++) {
12911 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12912 mInstrumentation.remove(a.getComponentName());
12913 if (DEBUG_REMOVE && chatty) {
12915 r = new StringBuilder(256);
12919 r.append(a.info.name);
12923 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
12927 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12928 // Only system apps can hold shared libraries.
12929 if (pkg.libraryNames != null) {
12930 final int libraryNamesSize = pkg.libraryNames.size();
12931 for (i = 0; i < libraryNamesSize; i++) {
12932 String name = pkg.libraryNames.get(i);
12933 if (removeSharedLibraryLPw(name, 0)) {
12934 if (DEBUG_REMOVE && chatty) {
12936 r = new StringBuilder(256);
12949 // Any package can hold static shared libraries.
12950 if (pkg.staticSharedLibName != null) {
12951 if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
12952 if (DEBUG_REMOVE && chatty) {
12954 r = new StringBuilder(256);
12958 r.append(pkg.staticSharedLibName);
12964 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r);
12969 public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
12970 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
12971 final int[] userIds, int[] instantUserIds) {
12972 mHandler.post(() -> {
12974 final IActivityManager am = ActivityManager.getService();
12975 if (am == null) return;
12976 final int[] resolvedUserIds;
12977 if (userIds == null) {
12978 resolvedUserIds = am.getRunningUserIds();
12980 resolvedUserIds = userIds;
12982 doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
12983 resolvedUserIds, false);
12984 if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
12985 doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
12986 instantUserIds, true);
12988 } catch (RemoteException ex) {
12994 public void notifyPackageAdded(String packageName, int uid) {
12995 final PackageListObserver[] observers;
12996 synchronized (mPackages) {
12997 if (mPackageListObservers.size() == 0) {
13000 final PackageListObserver[] observerArray =
13001 new PackageListObserver[mPackageListObservers.size()];
13002 observers = mPackageListObservers.toArray(observerArray);
13004 for (int i = observers.length - 1; i >= 0; --i) {
13005 observers[i].onPackageAdded(packageName, uid);
13010 public void notifyPackageChanged(String packageName, int uid) {
13011 final PackageListObserver[] observers;
13012 synchronized (mPackages) {
13013 if (mPackageListObservers.size() == 0) {
13016 final PackageListObserver[] observerArray =
13017 new PackageListObserver[mPackageListObservers.size()];
13018 observers = mPackageListObservers.toArray(observerArray);
13020 for (int i = observers.length - 1; i >= 0; --i) {
13021 observers[i].onPackageChanged(packageName, uid);
13025 private static final Comparator<ProviderInfo> sProviderInitOrderSorter = (p1, p2) -> {
13026 final int v1 = p1.initOrder;
13027 final int v2 = p2.initOrder;
13028 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
13032 public void notifyPackageRemoved(String packageName, int uid) {
13033 final PackageListObserver[] observers;
13034 synchronized (mPackages) {
13035 if (mPackageListObservers.size() == 0) {
13038 final PackageListObserver[] observerArray =
13039 new PackageListObserver[mPackageListObservers.size()];
13040 observers = mPackageListObservers.toArray(observerArray);
13042 for (int i = observers.length - 1; i >= 0; --i) {
13043 observers[i].onPackageRemoved(packageName, uid);
13048 * Sends a broadcast for the given action.
13049 * <p>If {@code isInstantApp} is {@code true}, then the broadcast is protected with
13050 * the {@link android.Manifest.permission#ACCESS_INSTANT_APPS} permission. This allows
13051 * the system and applications allowed to see instant applications to receive package
13052 * lifecycle events for instant applications.
13054 private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
13055 int flags, String targetPkg, IIntentReceiver finishedReceiver,
13056 int[] userIds, boolean isInstantApp)
13057 throws RemoteException {
13058 for (int id : userIds) {
13059 final Intent intent = new Intent(action,
13060 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
13061 final String[] requiredPermissions =
13062 isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null;
13063 if (extras != null) {
13064 intent.putExtras(extras);
13066 if (targetPkg != null) {
13067 intent.setPackage(targetPkg);
13069 // Modify the UID when posting to other users
13070 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13071 if (uid > 0 && UserHandle.getUserId(uid) != id) {
13072 uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13073 intent.putExtra(Intent.EXTRA_UID, uid);
13075 intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13076 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13077 if (DEBUG_BROADCASTS) {
13078 RuntimeException here = new RuntimeException("here");
13079 here.fillInStackTrace();
13080 Slog.d(TAG, "Sending to user " + id + ": "
13081 + intent.toShortString(false, true, false, false)
13082 + " " + intent.getExtras(), here);
13084 am.broadcastIntent(null, intent, null, finishedReceiver,
13085 0, null, null, requiredPermissions, android.app.AppOpsManager.OP_NONE,
13086 null, finishedReceiver != null, false, id);
13091 * Check if the external storage media is available. This is true if there
13092 * is a mounted external storage medium or if the external storage is
13095 private boolean isExternalMediaAvailable() {
13096 return mMediaMounted || Environment.isExternalStorageEmulated();
13100 * Ensure that the install reason matches what we know about the package installer (e.g. whether
13101 * it is acting on behalf on an enterprise or the user).
13103 * Note that the ordering of the conditionals in this method is important. The checks we perform
13104 * are as follows, in this order:
13106 * 1) If the install is being performed by a system app, we can trust the app to have set the
13107 * install reason correctly. Thus, we pass through the install reason unchanged, no matter
13109 * 2) If the install is being performed by a device or profile owner app, the install reason
13110 * should be enterprise policy. However, we cannot be sure that the device or profile owner
13111 * set the install reason correctly. If the app targets an older SDK version where install
13112 * reasons did not exist yet, or if the app author simply forgot, the install reason may be
13113 * unset or wrong. Thus, we force the install reason to be enterprise policy.
13114 * 3) In all other cases, the install is being performed by a regular app that is neither part
13115 * of the system nor a device or profile owner. We have no reason to believe that this app is
13116 * acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13117 * set to enterprise policy and if so, change it to unknown instead.
13119 private int fixUpInstallReason(String installerPackageName, int installerUid,
13120 int installReason) {
13121 if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13122 == PERMISSION_GRANTED) {
13123 // If the install is being performed by a system app, we trust that app to have set the
13124 // install reason correctly.
13125 return installReason;
13127 final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(
13128 UserHandle.getUserId(installerUid));
13129 if (ownerPackage != null && ownerPackage.equals(installerPackageName)) {
13130 // If the install is being performed by a device or profile owner, the install
13131 // reason should be enterprise policy.
13132 return PackageManager.INSTALL_REASON_POLICY;
13136 if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13137 // If the install is being performed by a regular app (i.e. neither system app nor
13138 // device or profile owner), we have no reason to believe that the app is acting on
13139 // behalf of an enterprise. If the app set the install reason to enterprise policy,
13140 // change it to unknown instead.
13141 return PackageManager.INSTALL_REASON_UNKNOWN;
13144 // If the install is being performed by a regular app and the install reason was set to any
13145 // value but enterprise policy, leave the install reason unchanged.
13146 return installReason;
13149 void installStage(ActiveInstallSession activeInstallSession) {
13150 if (DEBUG_INSTANT) {
13151 if ((activeInstallSession.getSessionParams().installFlags
13152 & PackageManager.INSTALL_INSTANT_APP) != 0) {
13153 Slog.d(TAG, "Ephemeral install of " + activeInstallSession.getPackageName());
13156 final Message msg = mHandler.obtainMessage(INIT_COPY);
13157 final InstallParams params = new InstallParams(activeInstallSession);
13158 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13161 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13162 System.identityHashCode(msg.obj));
13163 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13164 System.identityHashCode(msg.obj));
13166 mHandler.sendMessage(msg);
13169 void installStage(List<ActiveInstallSession> children)
13170 throws PackageManagerException {
13171 final Message msg = mHandler.obtainMessage(INIT_COPY);
13172 final MultiPackageInstallParams params =
13173 new MultiPackageInstallParams(UserHandle.ALL, children);
13174 params.setTraceMethod("installStageMultiPackage")
13175 .setTraceCookie(System.identityHashCode(params));
13178 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStageMultiPackage",
13179 System.identityHashCode(msg.obj));
13180 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13181 System.identityHashCode(msg.obj));
13182 mHandler.sendMessage(msg);
13185 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13187 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13188 final boolean isInstantApp = pkgSetting.getInstantApp(userId);
13189 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
13190 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
13191 sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
13192 false /*startReceiver*/, pkgSetting.appId, userIds, instantUserIds);
13194 // Send a session commit broadcast
13195 final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
13196 info.installReason = pkgSetting.getInstallReason(userId);
13197 info.appPackageName = packageName;
13198 sendSessionCommitBroadcast(info, userId);
13202 public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
13203 boolean includeStopped, int appId, int[] userIds, int[] instantUserIds) {
13204 if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
13207 Bundle extras = new Bundle(1);
13208 // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13209 final int uid = UserHandle.getUid(
13210 (ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId);
13211 extras.putInt(Intent.EXTRA_UID, uid);
13213 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
13214 packageName, extras, 0, null, null, userIds, instantUserIds);
13215 if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
13216 mHandler.post(() -> {
13217 for (int userId : userIds) {
13218 sendBootCompletedBroadcastToSystemApp(
13219 packageName, includeStopped, userId);
13227 * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13228 * automatically without needing an explicit launch.
13229 * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13231 private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
13233 // If user is not running, the app didn't miss any broadcast
13234 if (!mUserManagerInternal.isUserRunning(userId)) {
13237 final IActivityManager am = ActivityManager.getService();
13239 // Deliver LOCKED_BOOT_COMPLETED first
13240 Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13241 .setPackage(packageName);
13242 if (includeStopped) {
13243 lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13245 final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13246 am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13247 android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13249 // Deliver BOOT_COMPLETED only if user is unlocked
13250 if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13251 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13252 if (includeStopped) {
13253 bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13255 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13256 android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13258 } catch (RemoteException e) {
13259 throw e.rethrowFromSystemServer();
13264 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13266 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13267 PackageSetting pkgSetting;
13268 final int callingUid = Binder.getCallingUid();
13269 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13270 true /* requireFullPermission */, true /* checkShell */,
13271 "setApplicationHiddenSetting for user " + userId);
13273 if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13274 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13278 long callingId = Binder.clearCallingIdentity();
13280 boolean sendAdded = false;
13281 boolean sendRemoved = false;
13283 synchronized (mPackages) {
13284 pkgSetting = mSettings.mPackages.get(packageName);
13285 if (pkgSetting == null) {
13288 if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13291 // Do not allow "android" is being disabled
13292 if ("android".equals(packageName)) {
13293 Slog.w(TAG, "Cannot hide package: android");
13296 // Cannot hide static shared libs as they are considered
13297 // a part of the using app (emulating static linking). Also
13298 // static libs are installed always on internal storage.
13299 PackageParser.Package pkg = mPackages.get(packageName);
13300 if (pkg != null && pkg.staticSharedLibName != null) {
13301 Slog.w(TAG, "Cannot hide package: " + packageName
13302 + " providing static shared library: "
13303 + pkg.staticSharedLibName);
13306 // Only allow protected packages to hide themselves.
13307 if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
13308 && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13309 Slog.w(TAG, "Not hiding protected package: " + packageName);
13313 if (pkgSetting.getHidden(userId) != hidden) {
13314 pkgSetting.setHidden(hidden, userId);
13315 mSettings.writePackageRestrictionsLPr(userId);
13317 sendRemoved = true;
13324 sendPackageAddedForUser(packageName, pkgSetting, userId);
13328 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13330 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13334 Binder.restoreCallingIdentity(callingId);
13340 public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) {
13341 enforceSystemOrPhoneCaller("setSystemAppHiddenUntilInstalled");
13342 synchronized (mPackages) {
13343 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13344 if (pkgSetting == null || !pkgSetting.isSystem()) {
13347 PackageParser.Package pkg = pkgSetting.pkg;
13348 if (pkg != null && pkg.applicationInfo != null) {
13349 pkg.applicationInfo.hiddenUntilInstalled = hidden;
13351 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(packageName);
13352 if (disabledPs == null) {
13355 pkg = disabledPs.pkg;
13356 if (pkg != null && pkg.applicationInfo != null) {
13357 pkg.applicationInfo.hiddenUntilInstalled = hidden;
13363 public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
13364 enforceSystemOrPhoneCaller("setSystemAppInstallState");
13365 synchronized (mPackages) {
13366 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13367 // The target app should always be in system
13368 if (pkgSetting == null || !pkgSetting.isSystem()) {
13371 // Check if the install state is the same
13372 if (pkgSetting.getInstalled(userId) == installed) {
13377 final long callingId = Binder.clearCallingIdentity();
13380 // install the app from uninstalled state
13381 installExistingPackageAsUser(
13384 PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
13385 PackageManager.INSTALL_REASON_DEVICE_SETUP,
13390 // uninstall the app from installed state
13391 deletePackageVersioned(
13392 new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
13393 new LegacyPackageDeleteObserver(null).getBinder(),
13395 PackageManager.DELETE_SYSTEM_APP);
13398 Binder.restoreCallingIdentity(callingId);
13402 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13404 final PackageRemovedInfo info = new PackageRemovedInfo(this);
13405 info.removedPackage = packageName;
13406 info.installerPackageName = pkgSetting.installerPackageName;
13407 info.removedUsers = new int[] {userId};
13408 info.broadcastUsers = new int[] {userId};
13409 info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13410 info.sendPackageRemovedBroadcasts(true /*killApp*/);
13413 private void sendDistractingPackagesChanged(String[] pkgList, int[] uidList, int userId,
13414 int distractionFlags) {
13415 final Bundle extras = new Bundle(3);
13416 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13417 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
13418 extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags);
13419 sendPackageBroadcast(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null, extras,
13420 Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, new int[]{userId}, null);
13423 private void sendPackagesSuspendedForUser(String[] pkgList, int[] uidList, int userId,
13424 boolean suspended, PersistableBundle launcherExtras) {
13425 final Bundle extras = new Bundle(3);
13426 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13427 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
13428 if (launcherExtras != null) {
13429 extras.putBundle(Intent.EXTRA_LAUNCHER_EXTRAS,
13430 new Bundle(launcherExtras.deepCopy()));
13432 sendPackageBroadcast(
13433 suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13434 : Intent.ACTION_PACKAGES_UNSUSPENDED,
13435 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13436 new int[] {userId}, null);
13440 * Returns true if application is not found or there was an error. Otherwise it returns
13441 * the hidden state of the package for the given user.
13444 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
13445 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13446 final int callingUid = Binder.getCallingUid();
13447 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13448 true /* requireFullPermission */, false /* checkShell */,
13449 "getApplicationHidden for user " + userId);
13451 long callingId = Binder.clearCallingIdentity();
13454 synchronized (mPackages) {
13455 ps = mSettings.mPackages.get(packageName);
13459 if (filterAppAccessLPr(ps, callingUid, userId)) {
13462 return ps.getHidden(userId);
13465 Binder.restoreCallingIdentity(callingId);
13473 public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
13474 int installReason, List<String> whiteListedPermissions) {
13475 return installExistingPackageAsUser(packageName, userId, installFlags, installReason,
13476 whiteListedPermissions, null);
13479 int installExistingPackageAsUser(@Nullable String packageName, @UserIdInt int userId,
13480 @PackageManager.InstallFlags int installFlags,
13481 @PackageManager.InstallReason int installReason,
13482 @Nullable List<String> whiteListedPermissions, @Nullable IntentSender intentSender) {
13483 if (DEBUG_INSTALL) {
13484 Log.v(TAG, "installExistingPackageAsUser package=" + packageName + " userId=" + userId
13485 + " installFlags=" + installFlags + " installReason=" + installReason
13486 + " whiteListedPermissions=" + whiteListedPermissions);
13489 final int callingUid = Binder.getCallingUid();
13490 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES)
13491 != PackageManager.PERMISSION_GRANTED
13492 && mContext.checkCallingOrSelfPermission(
13493 android.Manifest.permission.INSTALL_EXISTING_PACKAGES)
13494 != PackageManager.PERMISSION_GRANTED) {
13495 throw new SecurityException("Neither user " + callingUid + " nor current process has "
13496 + android.Manifest.permission.INSTALL_PACKAGES + ".");
13498 PackageSetting pkgSetting;
13499 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13500 true /* requireFullPermission */, true /* checkShell */,
13501 "installExistingPackage for user " + userId);
13502 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13503 return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
13506 long callingId = Binder.clearCallingIdentity();
13508 boolean installed = false;
13509 final boolean instantApp =
13510 (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
13511 final boolean fullApp =
13512 (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
13515 synchronized (mPackages) {
13516 pkgSetting = mSettings.mPackages.get(packageName);
13517 if (pkgSetting == null) {
13518 return PackageManager.INSTALL_FAILED_INVALID_URI;
13520 if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
13521 // only allow the existing package to be used if it's installed as a full
13522 // application for at least one user
13523 boolean installAllowed = false;
13524 for (int checkUserId : sUserManager.getUserIds()) {
13525 installAllowed = !pkgSetting.getInstantApp(checkUserId);
13526 if (installAllowed) {
13530 if (!installAllowed) {
13531 return PackageManager.INSTALL_FAILED_INVALID_URI;
13534 if (!pkgSetting.getInstalled(userId)) {
13535 pkgSetting.setInstalled(true, userId);
13536 pkgSetting.setHidden(false, userId);
13537 pkgSetting.setInstallReason(installReason, userId);
13538 mSettings.writePackageRestrictionsLPr(userId);
13539 mSettings.writeKernelMappingLPr(pkgSetting);
13541 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13542 // upgrade app from instant to full; we don't allow app downgrade
13545 setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
13549 if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS)
13550 != 0 && pkgSetting.pkg != null) {
13551 whiteListedPermissions = pkgSetting.pkg.requestedPermissions;
13553 setWhitelistedRestrictedPermissions(packageName, whiteListedPermissions,
13554 PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER, userId);
13556 if (pkgSetting.pkg != null) {
13557 synchronized (mInstallLock) {
13558 // We don't need to freeze for a brand new install
13559 prepareAppDataAfterInstallLIF(pkgSetting.pkg);
13562 sendPackageAddedForUser(packageName, pkgSetting, userId);
13563 synchronized (mPackages) {
13564 updateSequenceNumberLP(pkgSetting, new int[]{ userId });
13566 // start async restore with no post-install since we finish install here
13567 PackageInstalledInfo res =
13568 createPackageInstalledInfo(PackageManager.INSTALL_SUCCEEDED);
13569 res.pkg = pkgSetting.pkg;
13570 res.newUsers = new int[]{ userId };
13571 PostInstallData postInstallData = intentSender == null ? null :
13572 new PostInstallData(null, res, () -> onRestoreComplete(res.returnCode,
13573 mContext, intentSender));
13574 restoreAndPostInstall(userId, res, postInstallData);
13577 Binder.restoreCallingIdentity(callingId);
13580 return PackageManager.INSTALL_SUCCEEDED;
13583 static void onRestoreComplete(int returnCode, Context context, IntentSender target) {
13584 Intent fillIn = new Intent();
13585 fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
13586 PackageManager.installStatusToPublicStatus(returnCode));
13588 target.sendIntent(context, 0, fillIn, null, null);
13589 } catch (SendIntentException ignored) {
13593 static void setInstantAppForUser(PackageSetting pkgSetting, int userId,
13594 boolean instantApp, boolean fullApp) {
13595 // no state specified; do nothing
13596 if (!instantApp && !fullApp) {
13599 if (userId != UserHandle.USER_ALL) {
13600 if (instantApp && !pkgSetting.getInstantApp(userId)) {
13601 pkgSetting.setInstantApp(true /*instantApp*/, userId);
13602 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13603 pkgSetting.setInstantApp(false /*instantApp*/, userId);
13606 for (int currentUserId : sUserManager.getUserIds()) {
13607 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
13608 pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
13609 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
13610 pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
13616 boolean isUserRestricted(int userId, String restrictionKey) {
13617 Bundle restrictions = sUserManager.getUserRestrictions(userId);
13618 if (restrictions.getBoolean(restrictionKey, false)) {
13619 Log.w(TAG, "User is restricted: " + restrictionKey);
13626 public String[] setDistractingPackageRestrictionsAsUser(String[] packageNames,
13627 int restrictionFlags, int userId) {
13628 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
13629 "setDistractingPackageRestrictionsAsUser");
13631 final int callingUid = Binder.getCallingUid();
13632 if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID
13633 && UserHandle.getUserId(callingUid) != userId) {
13634 throw new SecurityException("Calling uid " + callingUid + " cannot call for user "
13637 Preconditions.checkNotNull(packageNames, "packageNames cannot be null");
13639 final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
13640 final IntArray changedUids = new IntArray(packageNames.length);
13641 final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
13642 final boolean[] canRestrict = (restrictionFlags != 0) ? canSuspendPackageForUserInternal(
13643 packageNames, userId) : null;
13645 for (int i = 0; i < packageNames.length; i++) {
13646 final String packageName = packageNames[i];
13647 final PackageSetting pkgSetting;
13648 synchronized (mPackages) {
13649 pkgSetting = mSettings.mPackages.get(packageName);
13650 if (pkgSetting == null || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13651 Slog.w(TAG, "Could not find package setting for package: " + packageName
13652 + ". Skipping...");
13653 unactionedPackages.add(packageName);
13657 if (canRestrict != null && !canRestrict[i]) {
13658 unactionedPackages.add(packageName);
13661 synchronized (mPackages) {
13662 final int oldDistractionFlags = pkgSetting.getDistractionFlags(userId);
13663 if (restrictionFlags != oldDistractionFlags) {
13664 pkgSetting.setDistractionFlags(restrictionFlags, userId);
13665 changedPackagesList.add(packageName);
13666 changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
13671 if (!changedPackagesList.isEmpty()) {
13672 final String[] changedPackages = changedPackagesList.toArray(
13673 new String[changedPackagesList.size()]);
13674 sendDistractingPackagesChanged(changedPackages, changedUids.toArray(), userId,
13676 synchronized (mPackages) {
13677 scheduleWritePackageRestrictionsLocked(userId);
13680 return unactionedPackages.toArray(new String[0]);
13683 private void enforceCanSetPackagesSuspendedAsUser(String callingPackage, int callingUid,
13684 int userId, String callingMethod) {
13685 if (callingUid == Process.ROOT_UID || callingUid == Process.SYSTEM_UID) {
13689 final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
13690 if (ownerPackage != null) {
13691 final int ownerUid = getPackageUid(ownerPackage, 0, userId);
13692 if (ownerUid == callingUid) {
13695 throw new UnsupportedOperationException("Cannot suspend/unsuspend packages. User "
13696 + userId + " has an active DO or PO");
13699 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
13702 final int packageUid = getPackageUid(callingPackage, 0, userId);
13703 final boolean allowedPackageUid = packageUid == callingUid;
13704 final boolean allowedShell = callingUid == SHELL_UID
13705 && UserHandle.isSameApp(packageUid, callingUid);
13707 if (!allowedShell && !allowedPackageUid) {
13708 throw new SecurityException("Calling package " + callingPackage + " in user "
13709 + userId + " does not belong to calling uid " + callingUid);
13714 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
13715 PersistableBundle appExtras, PersistableBundle launcherExtras,
13716 SuspendDialogInfo dialogInfo, String callingPackage, int userId) {
13717 final int callingUid = Binder.getCallingUid();
13718 enforceCanSetPackagesSuspendedAsUser(callingPackage, callingUid, userId,
13719 "setPackagesSuspendedAsUser");
13721 if (ArrayUtils.isEmpty(packageNames)) {
13722 return packageNames;
13725 final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
13726 final IntArray changedUids = new IntArray(packageNames.length);
13727 final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
13728 final boolean[] canSuspend = suspended ? canSuspendPackageForUserInternal(packageNames,
13731 for (int i = 0; i < packageNames.length; i++) {
13732 final String packageName = packageNames[i];
13733 if (callingPackage.equals(packageName)) {
13734 Slog.w(TAG, "Calling package: " + callingPackage + " trying to "
13735 + (suspended ? "" : "un") + "suspend itself. Ignoring");
13736 unactionedPackages.add(packageName);
13739 final PackageSetting pkgSetting;
13740 synchronized (mPackages) {
13741 pkgSetting = mSettings.mPackages.get(packageName);
13742 if (pkgSetting == null || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13743 Slog.w(TAG, "Could not find package setting for package: " + packageName
13744 + ". Skipping suspending/un-suspending.");
13745 unactionedPackages.add(packageName);
13749 if (canSuspend != null && !canSuspend[i]) {
13750 unactionedPackages.add(packageName);
13753 synchronized (mPackages) {
13754 pkgSetting.setSuspended(suspended, callingPackage, dialogInfo, appExtras,
13755 launcherExtras, userId);
13757 changedPackagesList.add(packageName);
13758 changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
13761 if (!changedPackagesList.isEmpty()) {
13762 final String[] changedPackages = changedPackagesList.toArray(
13763 new String[changedPackagesList.size()]);
13764 sendPackagesSuspendedForUser(
13765 changedPackages, changedUids.toArray(), userId, suspended, launcherExtras);
13766 sendMyPackageSuspendedOrUnsuspended(changedPackages, suspended, appExtras, userId);
13767 synchronized (mPackages) {
13768 scheduleWritePackageRestrictionsLocked(userId);
13771 return unactionedPackages.toArray(new String[unactionedPackages.size()]);
13775 public PersistableBundle getSuspendedPackageAppExtras(String packageName, int userId) {
13776 final int callingUid = Binder.getCallingUid();
13777 if (getPackageUid(packageName, 0, userId) != callingUid) {
13778 throw new SecurityException("Calling package " + packageName
13779 + " does not belong to calling uid " + callingUid);
13781 synchronized (mPackages) {
13782 final PackageSetting ps = mSettings.mPackages.get(packageName);
13783 if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
13784 throw new IllegalArgumentException("Unknown target package: " + packageName);
13786 final PackageUserState packageUserState = ps.readUserState(userId);
13787 if (packageUserState.suspended) {
13788 return packageUserState.suspendedAppExtras;
13794 private void sendMyPackageSuspendedOrUnsuspended(String[] affectedPackages, boolean suspended,
13795 PersistableBundle appExtras, int userId) {
13796 final String action;
13797 final Bundle intentExtras = new Bundle();
13799 action = Intent.ACTION_MY_PACKAGE_SUSPENDED;
13800 if (appExtras != null) {
13801 final Bundle bundledAppExtras = new Bundle(appExtras.deepCopy());
13802 intentExtras.putBundle(Intent.EXTRA_SUSPENDED_PACKAGE_EXTRAS, bundledAppExtras);
13805 action = Intent.ACTION_MY_PACKAGE_UNSUSPENDED;
13807 mHandler.post(() -> {
13809 final IActivityManager am = ActivityManager.getService();
13811 Slog.wtf(TAG, "IActivityManager null. Cannot send MY_PACKAGE_ "
13812 + (suspended ? "" : "UN") + "SUSPENDED broadcasts");
13815 final int[] targetUserIds = new int[] {userId};
13816 for (String packageName : affectedPackages) {
13817 doSendBroadcast(am, action, null, intentExtras,
13818 Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, packageName, null,
13819 targetUserIds, false);
13821 } catch (RemoteException ex) {
13822 // Shouldn't happen as AMS is in the same process.
13828 public boolean isPackageSuspendedForUser(String packageName, int userId) {
13829 final int callingUid = Binder.getCallingUid();
13830 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13831 true /* requireFullPermission */, false /* checkShell */,
13832 "isPackageSuspendedForUser for user " + userId);
13833 synchronized (mPackages) {
13834 final PackageSetting ps = mSettings.mPackages.get(packageName);
13835 if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
13836 throw new IllegalArgumentException("Unknown target package: " + packageName);
13838 return ps.getSuspended(userId);
13843 * Immediately unsuspends any packages suspended by the given package. To be called
13844 * when such a package's data is cleared or it is removed from the device.
13846 * <p><b>Should not be used on a frequent code path</b> as it flushes state to disk
13849 * @param packageName The package holding {@link Manifest.permission#SUSPEND_APPS} permission
13850 * @param affectedUser The user for which the changes are taking place.
13852 void unsuspendForSuspendingPackage(final String packageName, int affectedUser) {
13853 final int[] userIds = (affectedUser == UserHandle.USER_ALL) ? sUserManager.getUserIds()
13854 : new int[] {affectedUser};
13855 for (int userId : userIds) {
13856 unsuspendForSuspendingPackages(packageName::equals, userId);
13861 * Immediately unsuspends any packages in the given users not suspended by the platform or root.
13862 * To be called when a profile owner or a device owner is added.
13864 * <p><b>Should not be used on a frequent code path</b> as it flushes state to disk
13867 * @param userIds The users for which to unsuspend packages
13869 void unsuspendForNonSystemSuspendingPackages(ArraySet<Integer> userIds) {
13870 final int sz = userIds.size();
13871 for (int i = 0; i < sz; i++) {
13872 unsuspendForSuspendingPackages(
13873 (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
13874 userIds.valueAt(i));
13878 private void unsuspendForSuspendingPackages(Predicate<String> packagePredicate, int userId) {
13879 final List<String> affectedPackages = new ArrayList<>();
13880 final IntArray affectedUids = new IntArray();
13881 synchronized (mPackages) {
13882 for (PackageSetting ps : mSettings.mPackages.values()) {
13883 final PackageUserState pus = ps.readUserState(userId);
13884 if (pus.suspended && packagePredicate.test(pus.suspendingPackage)) {
13885 ps.setSuspended(false, null, null, null, null, userId);
13886 affectedPackages.add(ps.name);
13887 affectedUids.add(UserHandle.getUid(userId, ps.getAppId()));
13891 if (!affectedPackages.isEmpty()) {
13892 final String[] packageArray = affectedPackages.toArray(
13893 new String[affectedPackages.size()]);
13894 sendMyPackageSuspendedOrUnsuspended(packageArray, false, null, userId);
13895 sendPackagesSuspendedForUser(
13896 packageArray, affectedUids.toArray(), userId, false, null);
13897 // Write package restrictions immediately to avoid an inconsistent state.
13898 mSettings.writePackageRestrictionsLPr(userId);
13903 public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) {
13904 Preconditions.checkNotNull("packageNames cannot be null", packageNames);
13905 mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
13906 "getUnsuspendablePackagesForUser");
13907 final int callingUid = Binder.getCallingUid();
13908 if (UserHandle.getUserId(callingUid) != userId) {
13909 throw new SecurityException("Calling uid " + callingUid
13910 + " cannot query getUnsuspendablePackagesForUser for user " + userId);
13912 final ArraySet<String> unactionablePackages = new ArraySet<>();
13913 final boolean[] canSuspend = canSuspendPackageForUserInternal(packageNames, userId);
13914 for (int i = 0; i < packageNames.length; i++) {
13915 if (!canSuspend[i]) {
13916 unactionablePackages.add(packageNames[i]);
13919 return unactionablePackages.toArray(new String[unactionablePackages.size()]);
13923 * Returns an array of booleans, such that the ith boolean denotes whether the ith package can
13924 * be suspended or not.
13926 * @param packageNames The package names to check suspendability for.
13927 * @param userId The user to check in
13928 * @return An array containing results of the checks
13931 private boolean[] canSuspendPackageForUserInternal(@NonNull String[] packageNames, int userId) {
13932 final boolean[] canSuspend = new boolean[packageNames.length];
13933 final long callingId = Binder.clearCallingIdentity();
13935 final String activeLauncherPackageName = getActiveLauncherPackageName(userId);
13936 final String dialerPackageName = getDefaultDialerPackageName(userId);
13937 for (int i = 0; i < packageNames.length; i++) {
13938 canSuspend[i] = false;
13939 final String packageName = packageNames[i];
13941 if (isPackageDeviceAdmin(packageName, userId)) {
13942 Slog.w(TAG, "Cannot suspend package \"" + packageName
13943 + "\": has an active device admin");
13946 if (packageName.equals(activeLauncherPackageName)) {
13947 Slog.w(TAG, "Cannot suspend package \"" + packageName
13948 + "\": contains the active launcher");
13951 if (packageName.equals(mRequiredInstallerPackage)) {
13952 Slog.w(TAG, "Cannot suspend package \"" + packageName
13953 + "\": required for package installation");
13956 if (packageName.equals(mRequiredUninstallerPackage)) {
13957 Slog.w(TAG, "Cannot suspend package \"" + packageName
13958 + "\": required for package uninstallation");
13961 if (packageName.equals(mRequiredVerifierPackage)) {
13962 Slog.w(TAG, "Cannot suspend package \"" + packageName
13963 + "\": required for package verification");
13966 if (packageName.equals(dialerPackageName)) {
13967 Slog.w(TAG, "Cannot suspend package \"" + packageName
13968 + "\": is the default dialer");
13971 if (packageName.equals(mRequiredPermissionControllerPackage)) {
13972 Slog.w(TAG, "Cannot suspend package \"" + packageName
13973 + "\": required for permissions management");
13976 synchronized (mPackages) {
13977 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13978 Slog.w(TAG, "Cannot suspend package \"" + packageName
13979 + "\": protected package");
13983 // Cannot suspend static shared libs as they are considered
13984 // a part of the using app (emulating static linking). Also
13985 // static libs are installed always on internal storage.
13986 PackageParser.Package pkg = mPackages.get(packageName);
13987 if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
13988 Slog.w(TAG, "Cannot suspend package: " + packageName
13989 + " providing static shared library: "
13990 + pkg.staticSharedLibName);
13994 if (PLATFORM_PACKAGE_NAME.equals(packageName)) {
13995 Slog.w(TAG, "Cannot suspend the platform package: " + packageName);
13998 canSuspend[i] = true;
14001 Binder.restoreCallingIdentity(callingId);
14006 private String getActiveLauncherPackageName(int userId) {
14007 Intent intent = new Intent(Intent.ACTION_MAIN);
14008 intent.addCategory(Intent.CATEGORY_HOME);
14009 ResolveInfo resolveInfo = resolveIntent(
14011 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
14012 PackageManager.MATCH_DEFAULT_ONLY,
14015 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
14019 private String getDefaultDialerPackageName(@UserIdInt int userId) {
14020 PackageManagerInternal.DefaultDialerProvider provider;
14021 synchronized (mPackages) {
14022 provider = mDefaultDialerProvider;
14024 if (provider == null) {
14025 Slog.e(TAG, "mDefaultDialerProvider is null");
14028 return provider.getDefaultDialer(userId);
14032 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
14033 mContext.enforceCallingOrSelfPermission(
14034 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14035 "Only package verification agents can verify applications");
14037 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14038 final PackageVerificationResponse response = new PackageVerificationResponse(
14039 verificationCode, Binder.getCallingUid());
14041 msg.obj = response;
14042 mHandler.sendMessage(msg);
14046 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
14047 long millisecondsToDelay) {
14048 mContext.enforceCallingOrSelfPermission(
14049 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14050 "Only package verification agents can extend verification timeouts");
14052 final PackageVerificationState state = mPendingVerification.get(id);
14053 final PackageVerificationResponse response = new PackageVerificationResponse(
14054 verificationCodeAtTimeout, Binder.getCallingUid());
14056 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
14057 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
14059 if (millisecondsToDelay < 0) {
14060 millisecondsToDelay = 0;
14062 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
14063 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
14064 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
14067 if ((state != null) && !state.timeoutExtended()) {
14068 state.extendTimeout();
14070 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14072 msg.obj = response;
14073 mHandler.sendMessageDelayed(msg, millisecondsToDelay);
14077 private void broadcastPackageVerified(int verificationId, Uri packageUri,
14078 int verificationCode, UserHandle user) {
14079 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
14080 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
14081 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14082 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14083 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
14085 mContext.sendBroadcastAsUser(intent, user,
14086 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
14089 private ComponentName matchComponentForVerifier(String packageName,
14090 List<ResolveInfo> receivers) {
14091 ActivityInfo targetReceiver = null;
14093 final int NR = receivers.size();
14094 for (int i = 0; i < NR; i++) {
14095 final ResolveInfo info = receivers.get(i);
14096 if (info.activityInfo == null) {
14100 if (packageName.equals(info.activityInfo.packageName)) {
14101 targetReceiver = info.activityInfo;
14106 if (targetReceiver == null) {
14110 return new ComponentName(targetReceiver.packageName, targetReceiver.name);
14113 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
14114 List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
14115 if (pkgInfo.verifiers.length == 0) {
14119 final int N = pkgInfo.verifiers.length;
14120 final List<ComponentName> sufficientVerifiers = new ArrayList<>(N + 1);
14121 for (int i = 0; i < N; i++) {
14122 final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
14124 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
14126 if (comp == null) {
14130 final int verifierUid = getUidForVerifier(verifierInfo);
14131 if (verifierUid == -1) {
14135 if (DEBUG_VERIFY) {
14136 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
14137 + " with the correct signature");
14139 sufficientVerifiers.add(comp);
14140 verificationState.addSufficientVerifier(verifierUid);
14143 return sufficientVerifiers;
14146 private int getUidForVerifier(VerifierInfo verifierInfo) {
14147 synchronized (mPackages) {
14148 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
14151 } else if (pkg.mSigningDetails.signatures.length != 1) {
14152 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14153 + " has more than one signature; ignoring");
14158 * If the public key of the package's signature does not match
14159 * our expected public key, then this is a different package and
14163 final byte[] expectedPublicKey;
14165 final Signature verifierSig = pkg.mSigningDetails.signatures[0];
14166 final PublicKey publicKey = verifierSig.getPublicKey();
14167 expectedPublicKey = publicKey.getEncoded();
14168 } catch (CertificateException e) {
14172 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
14174 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
14175 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14176 + " does not have the expected public key; ignoring");
14180 return pkg.applicationInfo.uid;
14184 private void setEnableRollbackCode(int token, int enableRollbackCode) {
14185 final Message msg = mHandler.obtainMessage(ENABLE_ROLLBACK_STATUS);
14187 msg.arg2 = enableRollbackCode;
14188 mHandler.sendMessage(msg);
14192 public void finishPackageInstall(int token, boolean didLaunch) {
14193 enforceSystemOrRoot("Only the system is allowed to finish installs");
14195 if (DEBUG_INSTALL) {
14196 Slog.v(TAG, "BM finishing package install for " + token);
14198 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14200 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
14201 mHandler.sendMessage(msg);
14205 * Get the verification agent timeout. Used for both the APK verifier and the
14206 * intent filter verifier.
14208 * @return verification timeout in milliseconds
14210 private long getVerificationTimeout() {
14211 return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
14212 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
14213 DEFAULT_VERIFICATION_TIMEOUT);
14217 * Get the default verification agent response code.
14219 * @return default verification response code
14221 private int getDefaultVerificationResponse(UserHandle user) {
14222 if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
14223 return PackageManager.VERIFICATION_REJECT;
14225 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14226 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
14227 DEFAULT_VERIFICATION_RESPONSE);
14231 * Check whether or not package verification has been enabled.
14233 * @return true if verification should be performed
14235 private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
14236 if (!DEFAULT_VERIFY_ENABLE) {
14240 if ((installFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0) {
14244 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
14246 // Check if installing from ADB
14247 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
14248 // Do not run verification in a test harness environment
14249 if (ActivityManager.isRunningInTestHarness()) {
14252 if (ensureVerifyAppsEnabled) {
14255 // Check if the developer does not want package verification for ADB installs
14256 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14257 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
14261 // only when not installed from ADB, skip verification for instant apps when
14262 // the installer and verifier are the same.
14263 if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14264 if (mInstantAppInstallerActivity != null
14265 && mInstantAppInstallerActivity.packageName.equals(
14266 mRequiredVerifierPackage)) {
14268 mContext.getSystemService(AppOpsManager.class)
14269 .checkPackage(installerUid, mRequiredVerifierPackage);
14270 if (DEBUG_VERIFY) {
14271 Slog.i(TAG, "disable verification for instant app");
14274 } catch (SecurityException ignore) { }
14279 if (ensureVerifyAppsEnabled) {
14283 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14284 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
14288 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
14289 throws RemoteException {
14290 mContext.enforceCallingOrSelfPermission(
14291 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
14292 "Only intentfilter verification agents can verify applications");
14294 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
14295 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
14296 Binder.getCallingUid(), verificationCode, failedDomains);
14298 msg.obj = response;
14299 mHandler.sendMessage(msg);
14303 public int getIntentVerificationStatus(String packageName, int userId) {
14304 final int callingUid = Binder.getCallingUid();
14305 if (UserHandle.getUserId(callingUid) != userId) {
14306 mContext.enforceCallingOrSelfPermission(
14307 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
14308 "getIntentVerificationStatus" + userId);
14310 if (getInstantAppPackageName(callingUid) != null) {
14311 return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14313 synchronized (mPackages) {
14314 final PackageSetting ps = mSettings.mPackages.get(packageName);
14316 || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
14317 return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14319 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
14324 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
14325 mContext.enforceCallingOrSelfPermission(
14326 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14328 boolean result = false;
14329 synchronized (mPackages) {
14330 final PackageSetting ps = mSettings.mPackages.get(packageName);
14331 if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14334 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
14337 scheduleWritePackageRestrictionsLocked(userId);
14343 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
14344 String packageName) {
14345 final int callingUid = Binder.getCallingUid();
14346 if (getInstantAppPackageName(callingUid) != null) {
14347 return ParceledListSlice.emptyList();
14349 synchronized (mPackages) {
14350 final PackageSetting ps = mSettings.mPackages.get(packageName);
14351 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
14352 return ParceledListSlice.emptyList();
14354 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
14359 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
14360 if (TextUtils.isEmpty(packageName)) {
14361 return ParceledListSlice.emptyList();
14363 final int callingUid = Binder.getCallingUid();
14364 final int callingUserId = UserHandle.getUserId(callingUid);
14365 synchronized (mPackages) {
14366 PackageParser.Package pkg = mPackages.get(packageName);
14367 if (pkg == null || pkg.activities == null) {
14368 return ParceledListSlice.emptyList();
14370 if (pkg.mExtras == null) {
14371 return ParceledListSlice.emptyList();
14373 final PackageSetting ps = (PackageSetting) pkg.mExtras;
14374 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
14375 return ParceledListSlice.emptyList();
14377 final int count = pkg.activities.size();
14378 ArrayList<IntentFilter> result = new ArrayList<>();
14379 for (int n=0; n<count; n++) {
14380 PackageParser.Activity activity = pkg.activities.get(n);
14381 if (activity.intents != null && activity.intents.size() > 0) {
14382 result.addAll(activity.intents);
14385 return new ParceledListSlice<>(result);
14390 public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14391 mContext.enforceCallingOrSelfPermission(
14392 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14393 if (UserHandle.getCallingUserId() != userId) {
14394 mContext.enforceCallingOrSelfPermission(
14395 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14397 if (userId == UserHandle.USER_ALL) {
14400 PackageManagerInternal.DefaultBrowserProvider provider;
14401 synchronized (mPackages) {
14402 provider = mDefaultBrowserProvider;
14404 if (provider == null) {
14405 Slog.e(TAG, "mDefaultBrowserProvider is null");
14408 boolean successful = provider.setDefaultBrowser(packageName, userId);
14412 if (packageName != null) {
14413 synchronized (mPackages) {
14414 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
14421 private void setDefaultBrowserAsyncLPw(@Nullable String packageName, @UserIdInt int userId) {
14422 if (userId == UserHandle.USER_ALL) {
14425 if (mDefaultBrowserProvider == null) {
14426 Slog.e(TAG, "mDefaultBrowserProvider is null");
14429 mDefaultBrowserProvider.setDefaultBrowserAsync(packageName, userId);
14430 if (packageName != null) {
14431 synchronized (mPackages) {
14432 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
14439 public String getDefaultBrowserPackageName(int userId) {
14440 if (UserHandle.getCallingUserId() != userId) {
14441 mContext.enforceCallingOrSelfPermission(
14442 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14444 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14447 PackageManagerInternal.DefaultBrowserProvider provider;
14448 synchronized (mPackages) {
14449 provider = mDefaultBrowserProvider;
14451 if (provider == null) {
14452 Slog.e(TAG, "mDefaultBrowserProvider is null");
14455 return provider.getDefaultBrowser(userId);
14459 * Get the "allow unknown sources" setting.
14461 * @return the current "allow unknown sources" setting
14463 private int getUnknownSourcesSettings() {
14464 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14465 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14470 public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14471 final int callingUid = Binder.getCallingUid();
14472 if (getInstantAppPackageName(callingUid) != null) {
14476 synchronized (mPackages) {
14477 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14478 if (targetPackageSetting == null
14479 || filterAppAccessLPr(
14480 targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
14481 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14484 PackageSetting installerPackageSetting;
14485 if (installerPackageName != null) {
14486 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14487 if (installerPackageSetting == null) {
14488 throw new IllegalArgumentException("Unknown installer package: "
14489 + installerPackageName);
14492 installerPackageSetting = null;
14495 Signature[] callerSignature;
14496 final int appId = UserHandle.getAppId(callingUid);
14497 final Object obj = mSettings.getSettingLPr(appId);
14499 if (obj instanceof SharedUserSetting) {
14501 ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
14502 } else if (obj instanceof PackageSetting) {
14503 callerSignature = ((PackageSetting)obj).signatures.mSigningDetails.signatures;
14505 throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
14508 throw new SecurityException("Unknown calling UID: " + callingUid);
14511 // Verify: can't set installerPackageName to a package that is
14512 // not signed with the same cert as the caller.
14513 if (installerPackageSetting != null) {
14514 if (compareSignatures(callerSignature,
14515 installerPackageSetting.signatures.mSigningDetails.signatures)
14516 != PackageManager.SIGNATURE_MATCH) {
14517 throw new SecurityException(
14518 "Caller does not have same cert as new installer package "
14519 + installerPackageName);
14523 // Verify: if target already has an installer package, it must
14524 // be signed with the same cert as the caller.
14525 if (targetPackageSetting.installerPackageName != null) {
14526 PackageSetting setting = mSettings.mPackages.get(
14527 targetPackageSetting.installerPackageName);
14528 // If the currently set package isn't valid, then it's always
14529 // okay to change it.
14530 if (setting != null) {
14531 if (compareSignatures(callerSignature,
14532 setting.signatures.mSigningDetails.signatures)
14533 != PackageManager.SIGNATURE_MATCH) {
14534 throw new SecurityException(
14535 "Caller does not have same cert as old installer package "
14536 + targetPackageSetting.installerPackageName);
14542 targetPackageSetting.installerPackageName = installerPackageName;
14543 if (installerPackageName != null) {
14544 mSettings.mInstallerPackages.add(installerPackageName);
14546 scheduleWriteSettingsLocked();
14551 public void setApplicationCategoryHint(String packageName, int categoryHint,
14552 String callerPackageName) {
14553 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14554 throw new SecurityException("Instant applications don't have access to this method");
14556 mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14557 callerPackageName);
14558 synchronized (mPackages) {
14559 PackageSetting ps = mSettings.mPackages.get(packageName);
14561 throw new IllegalArgumentException("Unknown target package " + packageName);
14563 if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14564 throw new IllegalArgumentException("Unknown target package " + packageName);
14566 if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14567 throw new IllegalArgumentException("Calling package " + callerPackageName
14568 + " is not installer for " + packageName);
14571 if (ps.categoryHint != categoryHint) {
14572 ps.categoryHint = categoryHint;
14573 scheduleWriteSettingsLocked();
14578 private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14579 if (args.mMultiPackageInstallParams != null) {
14580 args.mMultiPackageInstallParams.tryProcessInstallRequest(args, currentStatus);
14582 PackageInstalledInfo res = createPackageInstalledInfo(currentStatus);
14583 processInstallRequestsAsync(
14584 res.returnCode == PackageManager.INSTALL_SUCCEEDED,
14585 Collections.singletonList(new InstallRequest(args, res)));
14589 // Queue up an async operation since the package installation may take a little while.
14590 private void processInstallRequestsAsync(boolean success,
14591 List<InstallRequest> installRequests) {
14592 mHandler.post(() -> {
14594 for (InstallRequest request : installRequests) {
14595 request.args.doPreInstall(request.installResult.returnCode);
14597 synchronized (mInstallLock) {
14598 installPackagesTracedLI(installRequests);
14600 for (InstallRequest request : installRequests) {
14601 request.args.doPostInstall(
14602 request.installResult.returnCode, request.installResult.uid);
14605 for (InstallRequest request : installRequests) {
14606 restoreAndPostInstall(request.args.user.getIdentifier(), request.installResult,
14607 new PostInstallData(request.args, request.installResult, null));
14612 private PackageInstalledInfo createPackageInstalledInfo(
14613 int currentStatus) {
14614 PackageInstalledInfo res = new PackageInstalledInfo();
14615 res.setReturnCode(currentStatus);
14618 res.removedInfo = null;
14622 /** @param data Post-install is performed only if this is non-null. */
14623 private void restoreAndPostInstall(
14624 int userId, PackageInstalledInfo res, @Nullable PostInstallData data) {
14625 if (DEBUG_INSTALL) {
14626 Log.v(TAG, "restoreAndPostInstall userId=" + userId + " package="
14627 + res.pkg.packageName);
14630 // A restore should be performed at this point if (a) the install
14631 // succeeded, (b) the operation is not an update, and (c) the new
14632 // package has not opted out of backup participation.
14633 final boolean update = res.removedInfo != null
14634 && res.removedInfo.removedPackage != null;
14635 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
14636 boolean doRestore = !update
14637 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
14639 // Set up the post-install work request bookkeeping. This will be used
14640 // and cleaned up by the post-install event handling regardless of whether
14641 // there's a restore pass performed. Token values are >= 1.
14643 if (mNextInstallToken < 0) mNextInstallToken = 1;
14644 token = mNextInstallToken++;
14645 if (data != null) {
14646 mRunningInstalls.put(token, data);
14647 } else if (DEBUG_INSTALL) {
14648 Log.v(TAG, "No post-install required for " + token);
14651 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
14653 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
14654 // Pass responsibility to the Backup Manager. It will perform a
14655 // restore if appropriate, then pass responsibility back to the
14656 // Package Manager to run the post-install observer callbacks
14658 IBackupManager bm = IBackupManager.Stub.asInterface(
14659 ServiceManager.getService(Context.BACKUP_SERVICE));
14661 // For backwards compatibility as USER_ALL previously routed directly to USER_SYSTEM
14662 // in the BackupManager. USER_ALL is used in compatibility tests.
14663 if (userId == UserHandle.USER_ALL) {
14664 userId = UserHandle.USER_SYSTEM;
14666 if (DEBUG_INSTALL) {
14667 Log.v(TAG, "token " + token + " to BM for possible restore for user " + userId);
14669 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14671 if (bm.isBackupServiceActive(userId)) {
14672 bm.restoreAtInstallForUser(
14673 userId, res.pkg.applicationInfo.packageName, token);
14677 } catch (RemoteException e) {
14678 // can't happen; the backup manager is local
14679 } catch (Exception e) {
14680 Slog.e(TAG, "Exception trying to enqueue restore", e);
14684 Slog.e(TAG, "Backup Manager not found!");
14689 // If this is an update to a package that might be potentially downgraded, then we
14690 // need to check with the rollback manager whether there's any userdata that might
14691 // need to be restored for the package.
14693 // TODO(narayan): Get this working for cases where userId == UserHandle.USER_ALL.
14694 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && !doRestore && update) {
14695 IRollbackManager rm = IRollbackManager.Stub.asInterface(
14696 ServiceManager.getService(Context.ROLLBACK_SERVICE));
14698 final String packageName = res.pkg.applicationInfo.packageName;
14699 final String seInfo = res.pkg.applicationInfo.seInfo;
14700 final int[] allUsers = sUserManager.getUserIds();
14701 final int[] installedUsers;
14703 final PackageSetting ps;
14705 long ceDataInode = -1;
14706 synchronized (mSettings) {
14707 ps = mSettings.getPackageLPr(packageName);
14710 ceDataInode = ps.getCeDataInode(userId);
14713 // NOTE: We ignore the user specified in the InstallParam because we know this is
14714 // an update, and hence need to restore data for all installed users.
14715 installedUsers = ps.queryInstalledUsers(allUsers, true);
14720 rm.snapshotAndRestoreUserData(packageName, installedUsers, appId, ceDataInode,
14722 } catch (RemoteException re) {
14723 // Cannot happen, the RollbackManager is hosted in the same process.
14730 // No restore possible, or the Backup Manager was mysteriously not
14731 // available -- just fire the post-install work request directly.
14732 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
14734 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
14736 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
14737 mHandler.sendMessage(msg);
14742 * Callback from PackageSettings whenever an app is first transitioned out of the
14743 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if
14744 * the app was "launched" for a restoreAtInstall operation. Therefore we check
14745 * here whether the app is the target of an ongoing install, and only send the
14746 * broadcast immediately if it is not in that state. If it *is* undergoing a restore,
14747 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
14750 void notifyFirstLaunch(final String packageName, final String installerPackage,
14751 final int userId) {
14752 // Serialize this with the rest of the install-process message chain. In the
14753 // restore-at-install case, this Runnable will necessarily run before the
14754 // POST_INSTALL message is processed, so the contents of mRunningInstalls
14755 // are coherent. In the non-restore case, the app has already completed install
14756 // and been launched through some other means, so it is not in a problematic
14757 // state for observers to see the FIRST_LAUNCH signal.
14758 mHandler.post(() -> {
14759 for (int i = 0; i < mRunningInstalls.size(); i++) {
14760 final PostInstallData data = mRunningInstalls.valueAt(i);
14761 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14764 if (packageName.equals(data.res.pkg.applicationInfo.packageName)) {
14765 // right package; but is it for the right user?
14766 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
14767 if (userId == data.res.newUsers[uIndex]) {
14768 if (DEBUG_BACKUP) {
14769 Slog.i(TAG, "Package " + packageName
14770 + " being restored so deferring FIRST_LAUNCH");
14777 // didn't find it, so not being restored
14778 if (DEBUG_BACKUP) {
14779 Slog.i(TAG, "Package " + packageName + " sending normal FIRST_LAUNCH");
14781 final boolean isInstantApp = isInstantApp(packageName, userId);
14782 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
14783 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
14784 sendFirstLaunchBroadcast(packageName, installerPackage, userIds, instantUserIds);
14788 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg,
14789 int[] userIds, int[] instantUserIds) {
14790 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14791 installerPkg, null, userIds, instantUserIds);
14794 private abstract class HandlerParams {
14795 /** User handle for the user requesting the information or installation. */
14796 private final UserHandle mUser;
14797 String traceMethod;
14800 HandlerParams(UserHandle user) {
14804 UserHandle getUser() {
14809 * Gets the user handle for the user that the rollback agent should
14810 * use to look up information about this installation when enabling
14813 UserHandle getRollbackUser() {
14814 // The session for packages installed for "all" users is
14815 // associated with the "system" user.
14816 if (mUser == UserHandle.ALL) {
14817 return UserHandle.SYSTEM;
14822 HandlerParams setTraceMethod(String traceMethod) {
14823 this.traceMethod = traceMethod;
14827 HandlerParams setTraceCookie(int traceCookie) {
14828 this.traceCookie = traceCookie;
14832 final void startCopy() {
14833 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14835 handleReturnCode();
14838 abstract void handleStartCopy();
14839 abstract void handleReturnCode();
14842 static class OriginInfo {
14844 * Location where install is coming from, before it has been
14845 * copied/renamed into place. This could be a single monolithic APK
14846 * file, or a cluster directory. This location may be untrusted.
14851 * Flag indicating that {@link #file} has already been staged, meaning downstream users
14852 * don't need to defensively copy the contents.
14854 final boolean staged;
14857 * Flag indicating that {@link #file} is an already installed app that is being moved.
14859 final boolean existing;
14861 final String resolvedPath;
14862 final File resolvedFile;
14864 static OriginInfo fromNothing() {
14865 return new OriginInfo(null, false, false);
14868 static OriginInfo fromUntrustedFile(File file) {
14869 return new OriginInfo(file, false, false);
14872 static OriginInfo fromExistingFile(File file) {
14873 return new OriginInfo(file, false, true);
14876 static OriginInfo fromStagedFile(File file) {
14877 return new OriginInfo(file, true, false);
14880 private OriginInfo(File file, boolean staged, boolean existing) {
14882 this.staged = staged;
14883 this.existing = existing;
14885 if (file != null) {
14886 resolvedPath = file.getAbsolutePath();
14887 resolvedFile = file;
14889 resolvedPath = null;
14890 resolvedFile = null;
14895 static class MoveInfo {
14897 final String fromUuid;
14898 final String toUuid;
14899 final String packageName;
14900 final String dataAppName;
14902 final String seinfo;
14903 final int targetSdkVersion;
14905 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14906 String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14907 this.moveId = moveId;
14908 this.fromUuid = fromUuid;
14909 this.toUuid = toUuid;
14910 this.packageName = packageName;
14911 this.dataAppName = dataAppName;
14912 this.appId = appId;
14913 this.seinfo = seinfo;
14914 this.targetSdkVersion = targetSdkVersion;
14918 static class VerificationInfo {
14919 /** A constant used to indicate that a uid value is not present. */
14920 public static final int NO_UID = -1;
14922 /** URI referencing where the package was downloaded from. */
14923 final Uri originatingUri;
14925 /** HTTP referrer URI associated with the originatingURI. */
14926 final Uri referrer;
14928 /** UID of the application that the install request originated from. */
14929 final int originatingUid;
14931 /** UID of application requesting the install */
14932 final int installerUid;
14934 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14935 this.originatingUri = originatingUri;
14936 this.referrer = referrer;
14937 this.originatingUid = originatingUid;
14938 this.installerUid = installerUid;
14943 * Container for a multi-package install which refers to all install sessions and args being
14944 * committed together.
14946 class MultiPackageInstallParams extends HandlerParams {
14948 private int mRet = INSTALL_SUCCEEDED;
14950 private final ArrayList<InstallParams> mChildParams;
14952 private final Map<InstallArgs, Integer> mCurrentState;
14954 MultiPackageInstallParams(
14955 @NonNull UserHandle user,
14956 @NonNull List<ActiveInstallSession> activeInstallSessions)
14957 throws PackageManagerException {
14959 if (activeInstallSessions.size() == 0) {
14960 throw new PackageManagerException("No child sessions found!");
14962 mChildParams = new ArrayList<>(activeInstallSessions.size());
14963 for (int i = 0; i < activeInstallSessions.size(); i++) {
14964 final InstallParams childParams = new InstallParams(activeInstallSessions.get(i));
14965 childParams.mParentInstallParams = this;
14966 this.mChildParams.add(childParams);
14968 this.mCurrentState = new ArrayMap<>(mChildParams.size());
14972 void handleStartCopy() {
14973 for (InstallParams params : mChildParams) {
14974 params.handleStartCopy();
14975 if (params.mRet != INSTALL_SUCCEEDED) {
14976 mRet = params.mRet;
14982 void handleReturnCode() {
14983 for (InstallParams params : mChildParams) {
14984 params.handleReturnCode();
14985 if (params.mRet != INSTALL_SUCCEEDED) {
14986 mRet = params.mRet;
14991 void tryProcessInstallRequest(InstallArgs args, int currentStatus) {
14992 mCurrentState.put(args, currentStatus);
14993 if (mCurrentState.size() != mChildParams.size()) {
14996 int completeStatus = PackageManager.INSTALL_SUCCEEDED;
14997 for (Integer status : mCurrentState.values()) {
14998 if (status == PackageManager.INSTALL_UNKNOWN) {
15000 } else if (status != PackageManager.INSTALL_SUCCEEDED) {
15001 completeStatus = status;
15005 final List<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size());
15006 for (Map.Entry<InstallArgs, Integer> entry : mCurrentState.entrySet()) {
15007 installRequests.add(new InstallRequest(entry.getKey(),
15008 createPackageInstalledInfo(completeStatus)));
15010 processInstallRequestsAsync(
15011 completeStatus == PackageManager.INSTALL_SUCCEEDED,
15016 class InstallParams extends HandlerParams {
15017 // TODO: see if we can collapse this into ActiveInstallSession
15019 final OriginInfo origin;
15020 final MoveInfo move;
15021 final IPackageInstallObserver2 observer;
15023 final String installerPackageName;
15024 final String volumeUuid;
15025 private boolean mVerificationCompleted;
15026 private boolean mEnableRollbackCompleted;
15027 private InstallArgs mArgs;
15029 final String packageAbiOverride;
15030 final String[] grantedRuntimePermissions;
15031 final List<String> whitelistedRestrictedPermissions;
15032 final VerificationInfo verificationInfo;
15033 final PackageParser.SigningDetails signingDetails;
15034 final int installReason;
15036 MultiPackageInstallParams mParentInstallParams;
15037 final long requiredInstalledVersionCode;
15039 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15040 int installFlags, String installerPackageName, String volumeUuid,
15041 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
15042 String[] grantedPermissions, List<String> whitelistedRestrictedPermissions,
15043 PackageParser.SigningDetails signingDetails, int installReason,
15044 long requiredInstalledVersionCode) {
15046 this.origin = origin;
15048 this.observer = observer;
15049 this.installFlags = installFlags;
15050 this.installerPackageName = installerPackageName;
15051 this.volumeUuid = volumeUuid;
15052 this.verificationInfo = verificationInfo;
15053 this.packageAbiOverride = packageAbiOverride;
15054 this.grantedRuntimePermissions = grantedPermissions;
15055 this.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
15056 this.signingDetails = signingDetails;
15057 this.installReason = installReason;
15058 this.requiredInstalledVersionCode = requiredInstalledVersionCode;
15061 InstallParams(ActiveInstallSession activeInstallSession) {
15062 super(activeInstallSession.getUser());
15063 if (DEBUG_INSTANT) {
15064 if ((activeInstallSession.getSessionParams().installFlags
15065 & PackageManager.INSTALL_INSTANT_APP) != 0) {
15066 Slog.d(TAG, "Ephemeral install of " + activeInstallSession.getPackageName());
15069 verificationInfo = new VerificationInfo(
15070 activeInstallSession.getSessionParams().originatingUri,
15071 activeInstallSession.getSessionParams().referrerUri,
15072 activeInstallSession.getSessionParams().originatingUid,
15073 activeInstallSession.getInstallerUid());
15074 origin = OriginInfo.fromStagedFile(activeInstallSession.getStagedDir());
15076 installReason = fixUpInstallReason(activeInstallSession.getInstallerPackageName(),
15077 activeInstallSession.getInstallerUid(),
15078 activeInstallSession.getSessionParams().installReason);
15079 observer = activeInstallSession.getObserver();
15080 installFlags = activeInstallSession.getSessionParams().installFlags;
15081 installerPackageName = activeInstallSession.getInstallerPackageName();
15082 volumeUuid = activeInstallSession.getSessionParams().volumeUuid;
15083 packageAbiOverride = activeInstallSession.getSessionParams().abiOverride;
15084 grantedRuntimePermissions = activeInstallSession.getSessionParams()
15085 .grantedRuntimePermissions;
15086 whitelistedRestrictedPermissions = activeInstallSession.getSessionParams()
15087 .whitelistedRestrictedPermissions;
15088 signingDetails = activeInstallSession.getSigningDetails();
15089 requiredInstalledVersionCode = activeInstallSession.getSessionParams()
15090 .requiredInstalledVersionCode;
15094 public String toString() {
15095 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
15096 + " file=" + origin.file + "}";
15099 private int installLocationPolicy(PackageInfoLite pkgLite) {
15100 String packageName = pkgLite.packageName;
15101 int installLocation = pkgLite.installLocation;
15103 synchronized (mPackages) {
15104 // Currently installed package which the new package is attempting to replace or
15105 // null if no such package is installed.
15106 PackageParser.Package installedPkg = mPackages.get(packageName);
15107 // Package which currently owns the data which the new package will own if installed.
15108 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
15109 // will be null whereas dataOwnerPkg will contain information about the package
15110 // which was uninstalled while keeping its data.
15111 PackageParser.Package dataOwnerPkg = installedPkg;
15112 if (dataOwnerPkg == null) {
15113 PackageSetting ps = mSettings.mPackages.get(packageName);
15115 dataOwnerPkg = ps.pkg;
15119 if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST) {
15120 if (dataOwnerPkg == null) {
15121 Slog.w(TAG, "Required installed version code was "
15122 + requiredInstalledVersionCode
15123 + " but package is not installed");
15124 return PackageHelper.RECOMMEND_FAILED_WRONG_INSTALLED_VERSION;
15127 if (dataOwnerPkg.getLongVersionCode() != requiredInstalledVersionCode) {
15128 Slog.w(TAG, "Required installed version code was "
15129 + requiredInstalledVersionCode
15130 + " but actual installed version is "
15131 + dataOwnerPkg.getLongVersionCode());
15132 return PackageHelper.RECOMMEND_FAILED_WRONG_INSTALLED_VERSION;
15136 if (dataOwnerPkg != null) {
15137 if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags,
15138 dataOwnerPkg.applicationInfo.flags)) {
15140 checkDowngrade(dataOwnerPkg, pkgLite);
15141 } catch (PackageManagerException e) {
15142 Slog.w(TAG, "Downgrade detected: " + e.getMessage());
15143 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
15148 if (installedPkg != null) {
15149 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
15150 // Check for updated system application.
15151 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15152 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15154 // If current upgrade specifies particular preference
15155 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
15156 // Application explicitly specified internal.
15157 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15158 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
15159 // App explictly prefers external. Let policy decide
15161 // Prefer previous location
15162 if (isExternal(installedPkg)) {
15163 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15165 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15169 // Invalid install. Return error code
15170 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
15174 return pkgLite.recommendedInstallLocation;
15178 * Invoke remote method to get package information and install
15179 * location values. Override install location based on default
15180 * policy if needed and then create install arguments based
15181 * on the install location.
15183 public void handleStartCopy() {
15184 int ret = PackageManager.INSTALL_SUCCEEDED;
15186 // If we're already staged, we've firmly committed to an install location
15187 if (origin.staged) {
15188 if (origin.file != null) {
15189 installFlags |= PackageManager.INSTALL_INTERNAL;
15191 throw new IllegalStateException("Invalid stage location");
15195 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
15196 final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15197 PackageInfoLite pkgLite = null;
15200 pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
15201 origin.resolvedPath, installFlags, packageAbiOverride);
15203 if (DEBUG_INSTANT && ephemeral) {
15204 Slog.v(TAG, "pkgLite for install: " + pkgLite);
15208 * If we have too little free space, try to free cache
15209 * before giving up.
15211 if (!origin.staged && pkgLite.recommendedInstallLocation
15212 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15213 // TODO: focus freeing disk space on the target device
15214 final StorageManager storage = StorageManager.from(mContext);
15215 final long lowThreshold = storage.getStorageLowBytes(
15216 Environment.getDataDirectory());
15218 final long sizeBytes = PackageManagerServiceUtils.calculateInstalledSize(
15219 origin.resolvedPath, packageAbiOverride);
15220 if (sizeBytes >= 0) {
15222 mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
15223 pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
15224 origin.resolvedPath, installFlags, packageAbiOverride);
15225 } catch (InstallerException e) {
15226 Slog.w(TAG, "Failed to free cache", e);
15231 * The cache free must have deleted the file we downloaded to install.
15233 * TODO: fix the "freeCache" call to not delete the file we care about.
15235 if (pkgLite.recommendedInstallLocation
15236 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15237 pkgLite.recommendedInstallLocation
15238 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
15243 if (ret == PackageManager.INSTALL_SUCCEEDED) {
15244 int loc = pkgLite.recommendedInstallLocation;
15245 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
15246 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15247 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
15248 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
15249 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15250 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15251 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
15252 ret = PackageManager.INSTALL_FAILED_INVALID_APK;
15253 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15254 ret = PackageManager.INSTALL_FAILED_INVALID_URI;
15255 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
15256 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
15258 // Override with defaults if needed.
15259 loc = installLocationPolicy(pkgLite);
15260 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
15261 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
15262 } else if (loc == PackageHelper.RECOMMEND_FAILED_WRONG_INSTALLED_VERSION) {
15263 ret = PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION;
15264 } else if (!onInt) {
15265 // Override install location with flags
15266 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
15267 // Set the flag to install on external media.
15268 installFlags &= ~PackageManager.INSTALL_INTERNAL;
15269 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
15270 if (DEBUG_INSTANT) {
15271 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
15273 installFlags |= PackageManager.INSTALL_INSTANT_APP;
15274 installFlags &= ~PackageManager.INSTALL_INTERNAL;
15276 // Make sure the flag for installing on external
15278 installFlags |= PackageManager.INSTALL_INTERNAL;
15284 final InstallArgs args = createInstallArgs(this);
15285 mVerificationCompleted = true;
15286 mEnableRollbackCompleted = true;
15289 if (ret == PackageManager.INSTALL_SUCCEEDED) {
15290 // TODO: http://b/22976637
15291 // Apps installed for "all" users use the device owner to verify the app
15292 UserHandle verifierUser = getUser();
15293 if (verifierUser == UserHandle.ALL) {
15294 verifierUser = UserHandle.SYSTEM;
15298 * Determine if we have any installed package verifiers. If we
15299 * do, then we'll defer to them to verify the packages.
15301 final int requiredUid = mRequiredVerifierPackage == null ? -1
15302 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
15303 verifierUser.getIdentifier());
15304 final int installerUid =
15305 verificationInfo == null ? -1 : verificationInfo.installerUid;
15306 if (!origin.existing && requiredUid != -1
15307 && isVerificationEnabled(
15308 verifierUser.getIdentifier(), installFlags, installerUid)) {
15309 final Intent verification = new Intent(
15310 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
15311 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15312 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
15313 PACKAGE_MIME_TYPE);
15314 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15316 // Query all live verifiers based on current user state
15317 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
15318 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
15319 false /*allowDynamicSplits*/);
15321 if (DEBUG_VERIFY) {
15322 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
15323 + verification.toString() + " with " + pkgLite.verifiers.length
15324 + " optional verifiers");
15327 final int verificationId = mPendingVerificationToken++;
15329 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15331 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
15332 installerPackageName);
15334 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
15337 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
15338 pkgLite.packageName);
15340 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
15341 pkgLite.versionCode);
15343 verification.putExtra(PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
15344 pkgLite.getLongVersionCode());
15346 if (verificationInfo != null) {
15347 if (verificationInfo.originatingUri != null) {
15348 verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
15349 verificationInfo.originatingUri);
15351 if (verificationInfo.referrer != null) {
15352 verification.putExtra(Intent.EXTRA_REFERRER,
15353 verificationInfo.referrer);
15355 if (verificationInfo.originatingUid >= 0) {
15356 verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
15357 verificationInfo.originatingUid);
15359 if (verificationInfo.installerUid >= 0) {
15360 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
15361 verificationInfo.installerUid);
15365 final PackageVerificationState verificationState = new PackageVerificationState(
15366 requiredUid, this);
15368 mPendingVerification.append(verificationId, verificationState);
15370 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
15371 receivers, verificationState);
15373 DeviceIdleController.LocalService idleController = getDeviceIdleController();
15374 final long idleDuration = getVerificationTimeout();
15377 * If any sufficient verifiers were listed in the package
15378 * manifest, attempt to ask them.
15380 if (sufficientVerifiers != null) {
15381 final int N = sufficientVerifiers.size();
15383 Slog.i(TAG, "Additional verifiers required, but none installed.");
15384 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
15386 for (int i = 0; i < N; i++) {
15387 final ComponentName verifierComponent = sufficientVerifiers.get(i);
15388 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15389 verifierComponent.getPackageName(), idleDuration,
15390 verifierUser.getIdentifier(), false, "package verifier");
15392 final Intent sufficientIntent = new Intent(verification);
15393 sufficientIntent.setComponent(verifierComponent);
15394 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
15399 final ComponentName requiredVerifierComponent = matchComponentForVerifier(
15400 mRequiredVerifierPackage, receivers);
15401 if (ret == PackageManager.INSTALL_SUCCEEDED
15402 && mRequiredVerifierPackage != null) {
15403 Trace.asyncTraceBegin(
15404 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
15406 * Send the intent to the required verification agent,
15407 * but only start the verification timeout after the
15408 * target BroadcastReceivers have run.
15410 verification.setComponent(requiredVerifierComponent);
15411 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15412 mRequiredVerifierPackage, idleDuration,
15413 verifierUser.getIdentifier(), false, "package verifier");
15414 mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
15415 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15416 new BroadcastReceiver() {
15418 public void onReceive(Context context, Intent intent) {
15419 final Message msg = mHandler
15420 .obtainMessage(CHECK_PENDING_VERIFICATION);
15421 msg.arg1 = verificationId;
15422 mHandler.sendMessageDelayed(msg, getVerificationTimeout());
15424 }, null, 0, null, null);
15427 * We don't want the copy to proceed until verification
15430 mVerificationCompleted = false;
15434 if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
15435 // TODO(ruhler) b/112431924: Don't do this in case of 'move'?
15436 final int enableRollbackToken = mPendingEnableRollbackToken++;
15437 Trace.asyncTraceBegin(
15438 TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
15439 mPendingEnableRollback.append(enableRollbackToken, this);
15441 final int[] installedUsers;
15442 synchronized (mPackages) {
15443 PackageSetting ps = mSettings.getPackageLPr(pkgLite.packageName);
15445 installedUsers = ps.queryInstalledUsers(sUserManager.getUserIds(),
15448 installedUsers = new int[0];
15452 Intent enableRollbackIntent = new Intent(Intent.ACTION_PACKAGE_ENABLE_ROLLBACK);
15453 enableRollbackIntent.putExtra(
15454 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN,
15455 enableRollbackToken);
15456 enableRollbackIntent.putExtra(
15457 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALL_FLAGS,
15459 enableRollbackIntent.putExtra(
15460 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALLED_USERS,
15462 enableRollbackIntent.putExtra(
15463 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_USER,
15464 getRollbackUser().getIdentifier());
15465 enableRollbackIntent.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
15466 PACKAGE_MIME_TYPE);
15467 enableRollbackIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15469 // Allow the broadcast to be sent before boot complete.
15470 // This is needed when committing the apk part of a staged
15471 // session in early boot. The rollback manager registers
15472 // its receiver early enough during the boot process that
15473 // it will not miss the broadcast.
15474 enableRollbackIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
15476 mContext.sendOrderedBroadcastAsUser(enableRollbackIntent, UserHandle.SYSTEM,
15477 android.Manifest.permission.PACKAGE_ROLLBACK_AGENT,
15478 new BroadcastReceiver() {
15480 public void onReceive(Context context, Intent intent) {
15481 // the duration to wait for rollback to be enabled, in millis
15482 long rollbackTimeout = DeviceConfig.getLong(
15483 DeviceConfig.NAMESPACE_ROLLBACK,
15484 PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS,
15485 DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS);
15486 if (rollbackTimeout < 0) {
15487 rollbackTimeout = DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS;
15489 final Message msg = mHandler.obtainMessage(
15490 ENABLE_ROLLBACK_TIMEOUT);
15491 msg.arg1 = enableRollbackToken;
15492 mHandler.sendMessageDelayed(msg, rollbackTimeout);
15494 }, null, 0, null, null);
15496 mEnableRollbackCompleted = false;
15503 void setReturnCode(int ret) {
15504 if (mRet == PackageManager.INSTALL_SUCCEEDED) {
15505 // Only update mRet if it was previously INSTALL_SUCCEEDED to
15506 // ensure we do not overwrite any previous failure results.
15511 void handleVerificationFinished() {
15512 mVerificationCompleted = true;
15513 handleReturnCode();
15516 void handleRollbackEnabled() {
15517 // TODO(ruhler) b/112431924: Consider halting the install if we
15518 // couldn't enable rollback.
15519 mEnableRollbackCompleted = true;
15520 handleReturnCode();
15524 void handleReturnCode() {
15525 if (mVerificationCompleted && mEnableRollbackCompleted) {
15526 if ((installFlags & PackageManager.INSTALL_DRY_RUN) != 0) {
15527 String packageName = "";
15529 PackageLite packageInfo =
15530 new PackageParser().parsePackageLite(origin.file, 0);
15531 packageName = packageInfo.packageName;
15532 } catch (PackageParserException e) {
15533 Slog.e(TAG, "Can't parse package at " + origin.file.getAbsolutePath(), e);
15536 observer.onPackageInstalled(packageName, mRet, "Dry run", new Bundle());
15537 } catch (RemoteException e) {
15538 Slog.i(TAG, "Observer no longer exists.");
15542 if (mRet == PackageManager.INSTALL_SUCCEEDED) {
15543 mRet = mArgs.copyApk();
15545 processPendingInstall(mArgs, mRet);
15550 private InstallArgs createInstallArgs(InstallParams params) {
15551 if (params.move != null) {
15552 return new MoveInstallArgs(params);
15554 return new FileInstallArgs(params);
15559 * Create args that describe an existing installed package. Typically used
15560 * when cleaning up old installs, or used as a move source.
15562 private InstallArgs createInstallArgsForExisting(String codePath,
15563 String resourcePath, String[] instructionSets) {
15564 return new FileInstallArgs(codePath, resourcePath, instructionSets);
15567 static abstract class InstallArgs {
15568 /** @see InstallParams#origin */
15569 final OriginInfo origin;
15570 /** @see InstallParams#move */
15571 final MoveInfo move;
15573 final IPackageInstallObserver2 observer;
15574 // Always refers to PackageManager flags only
15575 final int installFlags;
15576 final String installerPackageName;
15577 final String volumeUuid;
15578 final UserHandle user;
15579 final String abiOverride;
15580 final String[] installGrantPermissions;
15581 final List<String> whitelistedRestrictedPermissions;
15582 /** If non-null, drop an async trace when the install completes */
15583 final String traceMethod;
15584 final int traceCookie;
15585 final PackageParser.SigningDetails signingDetails;
15586 final int installReason;
15587 @Nullable final MultiPackageInstallParams mMultiPackageInstallParams;
15589 // The list of instruction sets supported by this app. This is currently
15590 // only used during the rmdex() phase to clean up resources. We can get rid of this
15591 // if we move dex files under the common app path.
15592 /* nullable */ String[] instructionSets;
15594 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15595 int installFlags, String installerPackageName, String volumeUuid,
15596 UserHandle user, String[] instructionSets,
15597 String abiOverride, String[] installGrantPermissions,
15598 List<String> whitelistedRestrictedPermissions,
15599 String traceMethod, int traceCookie, SigningDetails signingDetails,
15601 MultiPackageInstallParams multiPackageInstallParams) {
15602 this.origin = origin;
15604 this.installFlags = installFlags;
15605 this.observer = observer;
15606 this.installerPackageName = installerPackageName;
15607 this.volumeUuid = volumeUuid;
15609 this.instructionSets = instructionSets;
15610 this.abiOverride = abiOverride;
15611 this.installGrantPermissions = installGrantPermissions;
15612 this.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
15613 this.traceMethod = traceMethod;
15614 this.traceCookie = traceCookie;
15615 this.signingDetails = signingDetails;
15616 this.installReason = installReason;
15617 this.mMultiPackageInstallParams = multiPackageInstallParams;
15620 abstract int copyApk();
15621 abstract int doPreInstall(int status);
15624 * Rename package into final resting place. All paths on the given
15625 * scanned package should be updated to reflect the rename.
15627 abstract boolean doRename(int status, PackageParser.Package pkg);
15628 abstract int doPostInstall(int status, int uid);
15630 /** @see PackageSettingBase#codePathString */
15631 abstract String getCodePath();
15632 /** @see PackageSettingBase#resourcePathString */
15633 abstract String getResourcePath();
15635 // Need installer lock especially for dex file removal.
15636 abstract void cleanUpResourcesLI();
15637 abstract boolean doPostDeleteLI(boolean delete);
15640 * Called before the source arguments are copied. This is used mostly
15641 * for MoveParams when it needs to read the source file to put it in the
15645 return PackageManager.INSTALL_SUCCEEDED;
15649 * Called after the source arguments are copied. This is used mostly for
15650 * MoveParams when it needs to read the source file to put it in the
15653 int doPostCopy(int uid) {
15654 return PackageManager.INSTALL_SUCCEEDED;
15657 protected boolean isEphemeral() {
15658 return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15661 UserHandle getUser() {
15666 void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15667 if (!allCodePaths.isEmpty()) {
15668 if (instructionSets == null) {
15669 throw new IllegalStateException("instructionSet == null");
15671 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15672 for (String codePath : allCodePaths) {
15673 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15675 mInstaller.rmdex(codePath, dexCodeInstructionSet);
15676 } catch (InstallerException ignored) {
15684 * Logic to handle installation of new applications, including copying
15685 * and renaming logic.
15687 class FileInstallArgs extends InstallArgs {
15688 private File codeFile;
15689 private File resourceFile;
15691 // Example topology:
15692 // /data/app/com.example/base.apk
15693 // /data/app/com.example/split_foo.apk
15694 // /data/app/com.example/lib/arm/libfoo.so
15695 // /data/app/com.example/lib/arm64/libfoo.so
15696 // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15699 FileInstallArgs(InstallParams params) {
15700 super(params.origin, params.move, params.observer, params.installFlags,
15701 params.installerPackageName, params.volumeUuid,
15702 params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15703 params.grantedRuntimePermissions, params.whitelistedRestrictedPermissions,
15704 params.traceMethod, params.traceCookie, params.signingDetails,
15705 params.installReason, params.mParentInstallParams);
15708 /** Existing install */
15709 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15710 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15711 null, null, null, null, 0, PackageParser.SigningDetails.UNKNOWN,
15712 PackageManager.INSTALL_REASON_UNKNOWN, null /* parent */);
15713 this.codeFile = (codePath != null) ? new File(codePath) : null;
15714 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15718 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15720 return doCopyApk();
15722 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15726 private int doCopyApk() {
15727 if (origin.staged) {
15728 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15729 codeFile = origin.file;
15730 resourceFile = origin.file;
15731 return PackageManager.INSTALL_SUCCEEDED;
15735 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15736 final File tempDir =
15737 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15738 codeFile = tempDir;
15739 resourceFile = tempDir;
15740 } catch (IOException e) {
15741 Slog.w(TAG, "Failed to create copy file: " + e);
15742 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15745 int ret = PackageManagerServiceUtils.copyPackage(
15746 origin.file.getAbsolutePath(), codeFile);
15747 if (ret != PackageManager.INSTALL_SUCCEEDED) {
15748 Slog.e(TAG, "Failed to copy package");
15752 final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15753 NativeLibraryHelper.Handle handle = null;
15755 handle = NativeLibraryHelper.Handle.create(codeFile);
15756 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15758 } catch (IOException e) {
15759 Slog.e(TAG, "Copying native libraries failed", e);
15760 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15762 IoUtils.closeQuietly(handle);
15768 int doPreInstall(int status) {
15769 if (status != PackageManager.INSTALL_SUCCEEDED) {
15775 boolean doRename(int status, PackageParser.Package pkg) {
15776 if (status != PackageManager.INSTALL_SUCCEEDED) {
15781 final File targetDir = codeFile.getParentFile();
15782 final File beforeCodeFile = codeFile;
15783 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15785 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15787 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15788 } catch (ErrnoException e) {
15789 Slog.w(TAG, "Failed to rename", e);
15793 if (!SELinux.restoreconRecursive(afterCodeFile)) {
15794 Slog.w(TAG, "Failed to restorecon");
15798 // Reflect the rename internally
15799 codeFile = afterCodeFile;
15800 resourceFile = afterCodeFile;
15802 // Reflect the rename in scanned details
15804 pkg.setCodePath(afterCodeFile.getCanonicalPath());
15805 } catch (IOException e) {
15806 Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
15809 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15810 afterCodeFile, pkg.baseCodePath));
15811 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15812 afterCodeFile, pkg.splitCodePaths));
15814 // Reflect the rename in app info
15815 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15816 pkg.setApplicationInfoCodePath(pkg.codePath);
15817 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15818 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15819 pkg.setApplicationInfoResourcePath(pkg.codePath);
15820 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15821 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15826 int doPostInstall(int status, int uid) {
15827 if (status != PackageManager.INSTALL_SUCCEEDED) {
15834 String getCodePath() {
15835 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15839 String getResourcePath() {
15840 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15843 private boolean cleanUp() {
15844 if (codeFile == null || !codeFile.exists()) {
15848 removeCodePathLI(codeFile);
15850 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15851 resourceFile.delete();
15857 void cleanUpResourcesLI() {
15858 // Try enumerating all code paths before deleting
15859 List<String> allCodePaths = Collections.EMPTY_LIST;
15860 if (codeFile != null && codeFile.exists()) {
15862 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15863 allCodePaths = pkg.getAllCodePaths();
15864 } catch (PackageParserException e) {
15865 // Ignored; we tried our best
15870 removeDexFiles(allCodePaths, instructionSets);
15873 boolean doPostDeleteLI(boolean delete) {
15874 // XXX err, shouldn't we respect the delete flag?
15875 cleanUpResourcesLI();
15880 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15881 PackageManagerException {
15883 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15884 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15885 throw new PackageManagerException(copyRet, message);
15891 * Logic to handle movement of existing installed applications.
15893 class MoveInstallArgs extends InstallArgs {
15894 private File codeFile;
15895 private File resourceFile;
15898 MoveInstallArgs(InstallParams params) {
15899 super(params.origin, params.move, params.observer, params.installFlags,
15900 params.installerPackageName, params.volumeUuid,
15901 params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15902 params.grantedRuntimePermissions, params.whitelistedRestrictedPermissions,
15903 params.traceMethod, params.traceCookie, params.signingDetails,
15904 params.installReason, params.mParentInstallParams);
15908 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15909 + move.fromUuid + " to " + move.toUuid);
15910 synchronized (mInstaller) {
15912 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15913 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
15914 } catch (InstallerException e) {
15915 Slog.w(TAG, "Failed to move app", e);
15916 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15920 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
15921 resourceFile = codeFile;
15922 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15924 return PackageManager.INSTALL_SUCCEEDED;
15927 int doPreInstall(int status) {
15928 if (status != PackageManager.INSTALL_SUCCEEDED) {
15929 cleanUp(move.toUuid);
15934 boolean doRename(int status, PackageParser.Package pkg) {
15935 if (status != PackageManager.INSTALL_SUCCEEDED) {
15936 cleanUp(move.toUuid);
15940 // Reflect the move in app info
15941 pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15942 pkg.setApplicationInfoCodePath(pkg.codePath);
15943 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15944 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15945 pkg.setApplicationInfoResourcePath(pkg.codePath);
15946 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15947 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15952 int doPostInstall(int status, int uid) {
15953 if (status == PackageManager.INSTALL_SUCCEEDED) {
15954 cleanUp(move.fromUuid);
15956 cleanUp(move.toUuid);
15962 String getCodePath() {
15963 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15967 String getResourcePath() {
15968 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15971 private boolean cleanUp(String volumeUuid) {
15972 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15974 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15975 final int[] userIds = sUserManager.getUserIds();
15976 synchronized (mInstallLock) {
15977 // Clean up both app data and code
15978 // All package moves are frozen until finished
15980 // We purposefully exclude FLAG_STORAGE_EXTERNAL here, since
15981 // this task was only focused on moving data on internal storage.
15982 for (int userId : userIds) {
15984 mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
15985 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
15986 } catch (InstallerException e) {
15987 Slog.w(TAG, String.valueOf(e));
15990 removeCodePathLI(codeFile);
15995 void cleanUpResourcesLI() {
15996 throw new UnsupportedOperationException();
15999 boolean doPostDeleteLI(boolean delete) {
16000 throw new UnsupportedOperationException();
16004 private File getNextCodePath(File targetDir, String packageName) {
16006 SecureRandom random = new SecureRandom();
16007 byte[] bytes = new byte[16];
16009 random.nextBytes(bytes);
16010 String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
16011 result = new File(targetDir, packageName + "-" + suffix);
16012 } while (result.exists());
16016 // Utility method that returns the relative package path with respect
16017 // to the installation directory. Like say for /data/data/com.test-1.apk
16018 // string com.test-1 is returned.
16019 static String deriveCodePathName(String codePath) {
16020 if (codePath == null) {
16023 final File codeFile = new File(codePath);
16024 final String name = codeFile.getName();
16025 if (codeFile.isDirectory()) {
16027 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
16028 final int lastDot = name.lastIndexOf('.');
16029 return name.substring(0, lastDot);
16031 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
16036 static class PackageInstalledInfo {
16039 // The set of users that originally had this package installed.
16041 // The set of users that now have this package installed.
16043 PackageParser.Package pkg;
16046 String installerPackageName;
16047 PackageRemovedInfo removedInfo;
16048 ArrayMap<String, PackageInstalledInfo> addedChildPackages;
16050 public void setError(int code, String msg) {
16051 setReturnCode(code);
16052 setReturnMessage(msg);
16056 public void setError(String msg, PackageParserException e) {
16057 setReturnCode(e.error);
16058 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16059 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16060 for (int i = 0; i < childCount; i++) {
16061 addedChildPackages.valueAt(i).setError(msg, e);
16063 Slog.w(TAG, msg, e);
16066 public void setError(String msg, PackageManagerException e) {
16067 returnCode = e.error;
16068 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16069 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16070 for (int i = 0; i < childCount; i++) {
16071 addedChildPackages.valueAt(i).setError(msg, e);
16073 Slog.w(TAG, msg, e);
16076 public void setReturnCode(int returnCode) {
16077 this.returnCode = returnCode;
16078 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16079 for (int i = 0; i < childCount; i++) {
16080 addedChildPackages.valueAt(i).returnCode = returnCode;
16084 private void setReturnMessage(String returnMsg) {
16085 this.returnMsg = returnMsg;
16086 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16087 for (int i = 0; i < childCount; i++) {
16088 addedChildPackages.valueAt(i).returnMsg = returnMsg;
16092 // In some error cases we want to convey more info back to the observer
16093 String origPackage;
16094 String origPermission;
16097 private static void updateDigest(MessageDigest digest, File file) throws IOException {
16098 try (DigestInputStream digestStream =
16099 new DigestInputStream(new FileInputStream(file), digest)) {
16100 while (digestStream.read() != -1) {} // nothing to do; just plow through the file
16105 * Checks whether the parent or any of the child packages have a change shared
16106 * user. For a package to be a valid update the shred users of the parent and
16107 * the children should match. We may later support changing child shared users.
16108 * @param oldPkg The updated package.
16109 * @param newPkg The update package.
16110 * @return The shared user that change between the versions.
16112 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16113 PackageParser.Package newPkg) {
16114 // Check parent shared user
16115 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16116 return newPkg.packageName;
16118 // Check child shared users
16119 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16120 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16121 for (int i = 0; i < newChildCount; i++) {
16122 PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16123 // If this child was present, did it have the same shared user?
16124 for (int j = 0; j < oldChildCount; j++) {
16125 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16126 if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16127 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16128 return newChildPkg.packageName;
16135 private void removeNativeBinariesLI(PackageSetting ps) {
16136 // Remove the lib path for the parent package
16138 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16139 // Remove the lib path for the child packages
16140 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16141 for (int i = 0; i < childCount; i++) {
16142 PackageSetting childPs = null;
16143 synchronized (mPackages) {
16144 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16146 if (childPs != null) {
16147 NativeLibraryHelper.removeNativeBinariesLI(childPs
16148 .legacyNativeLibraryPathString);
16154 @GuardedBy("mPackages")
16155 private void enableSystemPackageLPw(PackageParser.Package pkg) {
16156 // Enable the parent package
16157 mSettings.enableSystemPackageLPw(pkg.packageName);
16158 // Enable the child packages
16159 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16160 for (int i = 0; i < childCount; i++) {
16161 PackageParser.Package childPkg = pkg.childPackages.get(i);
16162 mSettings.enableSystemPackageLPw(childPkg.packageName);
16166 @GuardedBy("mPackages")
16167 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16168 PackageParser.Package newPkg) {
16169 // Disable the parent package (parent always replaced)
16170 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16171 // Disable the child packages
16172 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16173 for (int i = 0; i < childCount; i++) {
16174 PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16175 final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16176 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16181 @GuardedBy("mPackages")
16182 private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16183 String installerPackageName) {
16184 // Enable the parent package
16185 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16186 // Enable the child packages
16187 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16188 for (int i = 0; i < childCount; i++) {
16189 PackageParser.Package childPkg = pkg.childPackages.get(i);
16190 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
16194 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
16195 int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
16196 // Update the parent package setting
16197 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
16198 res, user, installReason);
16199 // Update the child packages setting
16200 final int childCount = (newPackage.childPackages != null)
16201 ? newPackage.childPackages.size() : 0;
16202 for (int i = 0; i < childCount; i++) {
16203 PackageParser.Package childPackage = newPackage.childPackages.get(i);
16204 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
16205 updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
16206 childRes.origUsers, childRes, user, installReason);
16210 private void updateSettingsInternalLI(PackageParser.Package pkg,
16211 String installerPackageName, int[] allUsers, int[] installedForUsers,
16212 PackageInstalledInfo res, UserHandle user, int installReason) {
16213 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
16215 final String pkgName = pkg.packageName;
16217 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.codePath);
16218 synchronized (mPackages) {
16219 // NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
16220 mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
16221 mPermissionCallback);
16222 // For system-bundled packages, we assume that installing an upgraded version
16223 // of the package implies that the user actually wants to run that new code,
16224 // so we enable the package.
16225 PackageSetting ps = mSettings.mPackages.get(pkgName);
16226 final int userId = user.getIdentifier();
16228 if (isSystemApp(pkg)) {
16229 if (DEBUG_INSTALL) {
16230 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
16232 // Enable system package for requested users
16233 if (res.origUsers != null) {
16234 for (int origUserId : res.origUsers) {
16235 if (userId == UserHandle.USER_ALL || userId == origUserId) {
16236 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
16237 origUserId, installerPackageName);
16241 // Also convey the prior install/uninstall state
16242 if (allUsers != null && installedForUsers != null) {
16243 for (int currentUserId : allUsers) {
16244 final boolean installed = ArrayUtils.contains(
16245 installedForUsers, currentUserId);
16246 if (DEBUG_INSTALL) {
16247 Slog.d(TAG, " user " + currentUserId + " => " + installed);
16249 ps.setInstalled(installed, currentUserId);
16251 // these install state changes will be persisted in the
16252 // upcoming call to mSettings.writeLPr().
16255 // It's implied that when a user requests installation, they want the app to be
16256 // installed and enabled.
16257 if (userId != UserHandle.USER_ALL) {
16258 ps.setInstalled(true, userId);
16259 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
16262 // When replacing an existing package, preserve the original install reason for all
16263 // users that had the package installed before.
16264 final Set<Integer> previousUserIds = new ArraySet<>();
16265 if (res.removedInfo != null && res.removedInfo.installReasons != null) {
16266 final int installReasonCount = res.removedInfo.installReasons.size();
16267 for (int i = 0; i < installReasonCount; i++) {
16268 final int previousUserId = res.removedInfo.installReasons.keyAt(i);
16269 final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
16270 ps.setInstallReason(previousInstallReason, previousUserId);
16271 previousUserIds.add(previousUserId);
16275 // Set install reason for users that are having the package newly installed.
16276 if (userId == UserHandle.USER_ALL) {
16277 for (int currentUserId : sUserManager.getUserIds()) {
16278 if (!previousUserIds.contains(currentUserId)) {
16279 ps.setInstallReason(installReason, currentUserId);
16282 } else if (!previousUserIds.contains(userId)) {
16283 ps.setInstallReason(installReason, userId);
16285 mSettings.writeKernelMappingLPr(ps);
16287 res.name = pkgName;
16288 res.uid = pkg.applicationInfo.uid;
16290 mSettings.setInstallerPackageName(pkgName, installerPackageName);
16291 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16292 //to update install status
16293 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16294 mSettings.writeLPr();
16295 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16298 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16301 private static class InstallRequest {
16302 public final InstallArgs args;
16303 public final PackageInstalledInfo installResult;
16305 private InstallRequest(InstallArgs args, PackageInstalledInfo res) {
16307 this.installResult = res;
16311 @GuardedBy({"mInstallLock", "mPackages"})
16312 private void installPackagesTracedLI(List<InstallRequest> requests) {
16314 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages");
16315 installPackagesLI(requests);
16317 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16322 * Package state to commit to memory and disk after reconciliation has completed.
16324 private static class CommitRequest {
16325 final Map<String, ReconciledPackage> reconciledPackages;
16326 final int[] mAllUsers;
16328 private CommitRequest(Map<String, ReconciledPackage> reconciledPackages, int[] allUsers) {
16329 this.reconciledPackages = reconciledPackages;
16330 this.mAllUsers = allUsers;
16335 * Package scan results and related request details used to reconcile the potential addition of
16336 * one or more packages to the system.
16338 * Reconcile will take a set of package details that need to be committed to the system and make
16339 * sure that they are valid in the context of the system and the other installing apps. Any
16340 * invalid state or app will result in a failed reconciliation and thus whatever operation (such
16341 * as install) led to the request.
16343 private static class ReconcileRequest {
16344 public final Map<String, ScanResult> scannedPackages;
16346 public final Map<String, PackageParser.Package> allPackages;
16347 public final Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource;
16348 public final Map<String, InstallArgs> installArgs;
16349 public final Map<String, PackageInstalledInfo> installResults;
16350 public final Map<String, PrepareResult> preparedPackages;
16351 public final Map<String, VersionInfo> versionInfos;
16352 public final Map<String, PackageSetting> lastStaticSharedLibSettings;
16354 private ReconcileRequest(Map<String, ScanResult> scannedPackages,
16355 Map<String, InstallArgs> installArgs,
16356 Map<String, PackageInstalledInfo> installResults,
16357 Map<String, PrepareResult> preparedPackages,
16358 Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource,
16359 Map<String, PackageParser.Package> allPackages,
16360 Map<String, VersionInfo> versionInfos,
16361 Map<String, PackageSetting> lastStaticSharedLibSettings) {
16362 this.scannedPackages = scannedPackages;
16363 this.installArgs = installArgs;
16364 this.installResults = installResults;
16365 this.preparedPackages = preparedPackages;
16366 this.sharedLibrarySource = sharedLibrarySource;
16367 this.allPackages = allPackages;
16368 this.versionInfos = versionInfos;
16369 this.lastStaticSharedLibSettings = lastStaticSharedLibSettings;
16372 private ReconcileRequest(Map<String, ScanResult> scannedPackages,
16373 Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource,
16374 Map<String, PackageParser.Package> allPackages,
16375 Map<String, VersionInfo> versionInfos,
16376 Map<String, PackageSetting> lastStaticSharedLibSettings) {
16377 this(scannedPackages, Collections.emptyMap(), Collections.emptyMap(),
16378 Collections.emptyMap(), sharedLibrarySource, allPackages, versionInfos,
16379 lastStaticSharedLibSettings);
16382 private static class ReconcileFailure extends PackageManagerException {
16383 ReconcileFailure(String message) {
16384 super("Reconcile failed: " + message);
16386 ReconcileFailure(int reason, String message) {
16387 super(reason, "Reconcile failed: " + message);
16389 ReconcileFailure(PackageManagerException e) {
16390 this(e.error, e.getMessage());
16395 * A container of all data needed to commit a package to in-memory data structures and to disk.
16396 * TODO: move most of the data contained her into a PackageSetting for commit.
16398 private static class ReconciledPackage {
16399 public final ReconcileRequest request;
16400 public final PackageSetting pkgSetting;
16401 public final ScanResult scanResult;
16402 // TODO: Remove install-specific details from the reconcile result
16403 public final PackageInstalledInfo installResult;
16404 @Nullable public final PrepareResult prepareResult;
16405 @Nullable public final InstallArgs installArgs;
16406 public final DeletePackageAction deletePackageAction;
16407 public final List<SharedLibraryInfo> allowedSharedLibraryInfos;
16408 public final SigningDetails signingDetails;
16409 public final boolean sharedUserSignaturesChanged;
16410 public ArrayList<SharedLibraryInfo> collectedSharedLibraryInfos;
16411 public final boolean removeAppKeySetData;
16413 private ReconciledPackage(ReconcileRequest request,
16414 InstallArgs installArgs,
16415 PackageSetting pkgSetting,
16416 PackageInstalledInfo installResult,
16417 PrepareResult prepareResult,
16418 ScanResult scanResult,
16419 DeletePackageAction deletePackageAction,
16420 List<SharedLibraryInfo> allowedSharedLibraryInfos,
16421 SigningDetails signingDetails,
16422 boolean sharedUserSignaturesChanged,
16423 boolean removeAppKeySetData) {
16424 this.request = request;
16425 this.installArgs = installArgs;
16426 this.pkgSetting = pkgSetting;
16427 this.installResult = installResult;
16428 this.prepareResult = prepareResult;
16429 this.scanResult = scanResult;
16430 this.deletePackageAction = deletePackageAction;
16431 this.allowedSharedLibraryInfos = allowedSharedLibraryInfos;
16432 this.signingDetails = signingDetails;
16433 this.sharedUserSignaturesChanged = sharedUserSignaturesChanged;
16434 this.removeAppKeySetData = removeAppKeySetData;
16438 * Returns a combined set of packages containing the packages already installed combined
16439 * with the package(s) currently being installed. The to-be installed packages take
16440 * precedence and may shadow already installed packages.
16442 private Map<String, PackageParser.Package> getCombinedPackages() {
16443 final ArrayMap<String, PackageParser.Package> combinedPackages =
16444 new ArrayMap<>(request.allPackages.size() + request.scannedPackages.size());
16446 combinedPackages.putAll(request.allPackages);
16447 for (ScanResult scanResult : request.scannedPackages.values()) {
16448 combinedPackages.put(scanResult.pkgSetting.name, scanResult.request.pkg);
16450 return combinedPackages;
16454 @GuardedBy("mPackages")
16455 private static Map<String, ReconciledPackage> reconcilePackagesLocked(
16456 final ReconcileRequest request, KeySetManagerService ksms)
16457 throws ReconcileFailure {
16458 final Map<String, ScanResult> scannedPackages = request.scannedPackages;
16460 final Map<String, ReconciledPackage> result = new ArrayMap<>(scannedPackages.size());
16462 // make a copy of the existing set of packages so we can combine them with incoming packages
16463 final ArrayMap<String, PackageParser.Package> combinedPackages =
16464 new ArrayMap<>(request.allPackages.size() + scannedPackages.size());
16465 combinedPackages.putAll(request.allPackages);
16467 final Map<String, LongSparseArray<SharedLibraryInfo>> incomingSharedLibraries =
16470 for (String installPackageName : scannedPackages.keySet()) {
16471 final ScanResult scanResult = scannedPackages.get(installPackageName);
16473 // add / replace existing with incoming packages
16474 combinedPackages.put(scanResult.pkgSetting.name, scanResult.request.pkg);
16476 // in the first pass, we'll build up the set of incoming shared libraries
16477 final List<SharedLibraryInfo> allowedSharedLibInfos =
16478 getAllowedSharedLibInfos(scanResult, request.sharedLibrarySource);
16479 final SharedLibraryInfo staticLib = scanResult.staticSharedLibraryInfo;
16480 if (allowedSharedLibInfos != null) {
16481 for (SharedLibraryInfo info : allowedSharedLibInfos) {
16482 if (!addSharedLibraryToPackageVersionMap(incomingSharedLibraries, info)) {
16483 throw new ReconcileFailure("Static Shared Library " + staticLib.getName()
16484 + " is being installed twice in this set!");
16489 // the following may be null if we're just reconciling on boot (and not during install)
16490 final InstallArgs installArgs = request.installArgs.get(installPackageName);
16491 final PackageInstalledInfo res = request.installResults.get(installPackageName);
16492 final PrepareResult prepareResult = request.preparedPackages.get(installPackageName);
16493 final boolean isInstall = installArgs != null;
16494 if (isInstall && (res == null || prepareResult == null)) {
16495 throw new ReconcileFailure("Reconcile arguments are not balanced for "
16496 + installPackageName + "!");
16499 final DeletePackageAction deletePackageAction;
16500 // we only want to try to delete for non system apps
16501 if (isInstall && prepareResult.replace && !prepareResult.system) {
16502 final boolean killApp = (scanResult.request.scanFlags & SCAN_DONT_KILL_APP) == 0;
16503 final int deleteFlags = PackageManager.DELETE_KEEP_DATA
16504 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
16505 deletePackageAction = mayDeletePackageLocked(res.removedInfo,
16506 prepareResult.originalPs, prepareResult.disabledPs,
16507 prepareResult.childPackageSettings, deleteFlags, null /* all users */);
16508 if (deletePackageAction == null) {
16509 throw new ReconcileFailure(
16510 PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE,
16511 "May not delete " + installPackageName + " to replace");
16514 deletePackageAction = null;
16517 final int scanFlags = scanResult.request.scanFlags;
16518 final int parseFlags = scanResult.request.parseFlags;
16519 final PackageParser.Package pkg = scanResult.request.pkg;
16521 final PackageSetting disabledPkgSetting = scanResult.request.disabledPkgSetting;
16522 final PackageSetting lastStaticSharedLibSetting =
16523 request.lastStaticSharedLibSettings.get(installPackageName);
16524 final PackageSetting signatureCheckPs =
16525 (prepareResult != null && lastStaticSharedLibSetting != null)
16526 ? lastStaticSharedLibSetting
16527 : scanResult.pkgSetting;
16528 boolean removeAppKeySetData = false;
16529 boolean sharedUserSignaturesChanged = false;
16530 SigningDetails signingDetails = null;
16531 if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
16532 if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
16533 // We just determined the app is signed correctly, so bring
16534 // over the latest parsed certs.
16536 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
16537 throw new ReconcileFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16538 "Package " + pkg.packageName + " upgrade keys do not match the "
16539 + "previously installed version");
16541 String msg = "System package " + pkg.packageName
16542 + " signature changed; retaining data.";
16543 reportSettingsProblem(Log.WARN, msg);
16546 signingDetails = pkg.mSigningDetails;
16549 final VersionInfo versionInfo = request.versionInfos.get(installPackageName);
16550 final boolean compareCompat = isCompatSignatureUpdateNeeded(versionInfo);
16551 final boolean compareRecover = isRecoverSignatureUpdateNeeded(versionInfo);
16552 final boolean compatMatch = verifySignatures(signatureCheckPs,
16553 disabledPkgSetting, pkg.mSigningDetails, compareCompat, compareRecover);
16554 // The new KeySets will be re-added later in the scanning process.
16556 removeAppKeySetData = true;
16558 // We just determined the app is signed correctly, so bring
16559 // over the latest parsed certs.
16560 signingDetails = pkg.mSigningDetails;
16563 // if this is is a sharedUser, check to see if the new package is signed by a
16565 // signing certificate than the existing one, and if so, copy over the new
16567 if (signatureCheckPs.sharedUser != null) {
16568 if (pkg.mSigningDetails.hasAncestor(
16569 signatureCheckPs.sharedUser.signatures.mSigningDetails)) {
16570 signatureCheckPs.sharedUser.signatures.mSigningDetails =
16571 pkg.mSigningDetails;
16573 if (signatureCheckPs.sharedUser.signaturesChanged == null) {
16574 signatureCheckPs.sharedUser.signaturesChanged = Boolean.FALSE;
16577 } catch (PackageManagerException e) {
16578 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
16579 throw new ReconcileFailure(e);
16581 signingDetails = pkg.mSigningDetails;
16583 // If the system app is part of a shared user we allow that shared user to
16585 // signatures as well as part of an OTA. We still need to verify that the
16587 // are consistent within the shared user for a given boot, so only allow
16589 // the signatures on the first package scanned for the shared user (i.e. if the
16590 // signaturesChanged state hasn't been initialized yet in SharedUserSetting).
16591 if (signatureCheckPs.sharedUser != null) {
16592 final Signature[] sharedUserSignatures =
16593 signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures;
16594 if (signatureCheckPs.sharedUser.signaturesChanged != null
16595 && compareSignatures(sharedUserSignatures,
16596 pkg.mSigningDetails.signatures)
16597 != PackageManager.SIGNATURE_MATCH) {
16598 if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 29) {
16599 // Mismatched signatures is an error and silently skipping system
16600 // packages will likely break the device in unforeseen ways.
16601 // However, we allow the device to boot anyway because, prior to Q,
16602 // vendors were not expecting the platform to crash in this
16604 // This WILL be a hard failure on any new API levels after Q.
16605 throw new ReconcileFailure(
16606 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
16607 "Signature mismatch for shared user: "
16608 + scanResult.pkgSetting.sharedUser);
16610 // Treat mismatched signatures on system packages using a shared
16612 // fatal for the system overall, rather than just failing to install
16613 // whichever package happened to be scanned later.
16614 throw new IllegalStateException(
16615 "Signature mismatch on system package "
16616 + pkg.packageName + " for shared user "
16617 + scanResult.pkgSetting.sharedUser);
16621 sharedUserSignaturesChanged = true;
16622 signatureCheckPs.sharedUser.signatures.mSigningDetails =
16623 pkg.mSigningDetails;
16624 signatureCheckPs.sharedUser.signaturesChanged = Boolean.TRUE;
16626 // File a report about this.
16627 String msg = "System package " + pkg.packageName
16628 + " signature changed; retaining data.";
16629 reportSettingsProblem(Log.WARN, msg);
16630 } catch (IllegalArgumentException e) {
16631 // should never happen: certs matched when checking, but not when comparing
16632 // old to new for sharedUser
16633 throw new RuntimeException(
16634 "Signing certificates comparison made on incomparable signing details"
16635 + " but somehow passed verifySignatures!", e);
16639 result.put(installPackageName,
16640 new ReconciledPackage(request, installArgs, scanResult.pkgSetting,
16641 res, request.preparedPackages.get(installPackageName), scanResult,
16642 deletePackageAction, allowedSharedLibInfos, signingDetails,
16643 sharedUserSignaturesChanged, removeAppKeySetData));
16646 for (String installPackageName : scannedPackages.keySet()) {
16647 // Check all shared libraries and map to their actual file path.
16648 // We only do this here for apps not on a system dir, because those
16649 // are the only ones that can fail an install due to this. We
16650 // will take care of the system apps by updating all of their
16651 // library paths after the scan is done. Also during the initial
16652 // scan don't update any libs as we do this wholesale after all
16653 // apps are scanned to avoid dependency based scanning.
16654 final ScanResult scanResult = scannedPackages.get(installPackageName);
16655 if ((scanResult.request.scanFlags & SCAN_BOOTING) != 0
16656 || (scanResult.request.parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
16660 result.get(installPackageName).collectedSharedLibraryInfos =
16661 collectSharedLibraryInfos(scanResult.request.pkg, combinedPackages,
16662 request.sharedLibrarySource, incomingSharedLibraries);
16664 } catch (PackageManagerException e) {
16665 throw new ReconcileFailure(e.error, e.getMessage());
16673 * Compare the newly scanned package with current system state to see which of its declared
16674 * shared libraries should be allowed to be added to the system.
16676 private static List<SharedLibraryInfo> getAllowedSharedLibInfos(
16677 ScanResult scanResult,
16678 Map<String, LongSparseArray<SharedLibraryInfo>> existingSharedLibraries) {
16679 // Let's used the parsed package as scanResult.pkgSetting may be null
16680 final PackageParser.Package pkg = scanResult.request.pkg;
16681 if (scanResult.staticSharedLibraryInfo == null
16682 && scanResult.dynamicSharedLibraryInfos == null) {
16686 // Any app can add new static shared libraries
16687 if (scanResult.staticSharedLibraryInfo != null) {
16688 return Collections.singletonList(scanResult.staticSharedLibraryInfo);
16690 final boolean hasDynamicLibraries =
16691 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
16692 && scanResult.dynamicSharedLibraryInfos != null;
16693 if (!hasDynamicLibraries) {
16696 final boolean isUpdatedSystemApp = pkg.isUpdatedSystemApp();
16697 // We may not yet have disabled the updated package yet, so be sure to grab the
16698 // current setting if that's the case.
16699 final PackageSetting updatedSystemPs = isUpdatedSystemApp
16700 ? scanResult.request.disabledPkgSetting == null
16701 ? scanResult.request.oldPkgSetting
16702 : scanResult.request.disabledPkgSetting
16704 if (isUpdatedSystemApp && (updatedSystemPs.pkg == null
16705 || updatedSystemPs.pkg.libraryNames == null)) {
16706 Slog.w(TAG, "Package " + pkg.packageName + " declares libraries that are not "
16707 + "declared on the system image; skipping");
16710 final ArrayList<SharedLibraryInfo> infos =
16711 new ArrayList<>(scanResult.dynamicSharedLibraryInfos.size());
16712 for (SharedLibraryInfo info : scanResult.dynamicSharedLibraryInfos) {
16713 final String name = info.getName();
16714 if (isUpdatedSystemApp) {
16715 // New library entries can only be added through the
16716 // system image. This is important to get rid of a lot
16717 // of nasty edge cases: for example if we allowed a non-
16718 // system update of the app to add a library, then uninstalling
16719 // the update would make the library go away, and assumptions
16720 // we made such as through app install filtering would now
16721 // have allowed apps on the device which aren't compatible
16722 // with it. Better to just have the restriction here, be
16723 // conservative, and create many fewer cases that can negatively
16724 // impact the user experience.
16725 if (!updatedSystemPs.pkg.libraryNames.contains(name)) {
16726 Slog.w(TAG, "Package " + pkg.packageName + " declares library " + name
16727 + " that is not declared on system image; skipping");
16731 if (sharedLibExists(
16732 name, SharedLibraryInfo.VERSION_UNDEFINED, existingSharedLibraries)) {
16733 Slog.w(TAG, "Package " + pkg.packageName + " declares library " + name
16734 + " that already exists; skipping");
16743 * Returns false if the adding shared library already exists in the map and so could not be
16746 private static boolean addSharedLibraryToPackageVersionMap(
16747 Map<String, LongSparseArray<SharedLibraryInfo>> target,
16748 SharedLibraryInfo library) {
16749 final String name = library.getName();
16750 if (target.containsKey(name)) {
16751 if (library.getType() != SharedLibraryInfo.TYPE_STATIC) {
16752 // We've already added this non-version-specific library to the map.
16754 } else if (target.get(name).indexOfKey(library.getLongVersion()) >= 0) {
16755 // We've already added this version of a version-specific library to the map.
16759 target.put(name, new LongSparseArray<>());
16761 target.get(name).put(library.getLongVersion(), library);
16765 @GuardedBy("mPackages")
16766 private void commitPackagesLocked(final CommitRequest request) {
16767 // TODO: remove any expected failures from this method; this should only be able to fail due
16768 // to unavoidable errors (I/O, etc.)
16769 for (ReconciledPackage reconciledPkg : request.reconciledPackages.values()) {
16770 final ScanResult scanResult = reconciledPkg.scanResult;
16771 final ScanRequest scanRequest = scanResult.request;
16772 final PackageParser.Package pkg = scanRequest.pkg;
16773 final String packageName = pkg.packageName;
16774 final PackageInstalledInfo res = reconciledPkg.installResult;
16776 if (reconciledPkg.prepareResult.replace) {
16777 PackageParser.Package oldPackage = mPackages.get(packageName);
16779 // Set the update and install times
16780 PackageSetting deletedPkgSetting = (PackageSetting) oldPackage.mExtras;
16781 setInstallAndUpdateTime(pkg, deletedPkgSetting.firstInstallTime,
16782 System.currentTimeMillis());
16784 if (reconciledPkg.prepareResult.system) {
16785 // Remove existing system package
16786 removePackageLI(oldPackage, true);
16787 if (!disableSystemPackageLPw(oldPackage, pkg)) {
16788 // We didn't need to disable the .apk as a current system package,
16789 // which means we are replacing another update that is already
16790 // installed. We need to make sure to delete the older one's .apk.
16791 res.removedInfo.args = createInstallArgsForExisting(
16792 oldPackage.applicationInfo.getCodePath(),
16793 oldPackage.applicationInfo.getResourcePath(),
16794 getAppDexInstructionSets(oldPackage.applicationInfo));
16796 res.removedInfo.args = null;
16799 // Update the package dynamic state if succeeded
16800 // Now that the install succeeded make sure we remove data
16801 // directories for any child package the update removed.
16802 final int deletedChildCount = (oldPackage.childPackages != null)
16803 ? oldPackage.childPackages.size() : 0;
16804 final int newChildCount = (pkg.childPackages != null)
16805 ? pkg.childPackages.size() : 0;
16806 for (int i = 0; i < deletedChildCount; i++) {
16807 PackageParser.Package deletedChildPkg = oldPackage.childPackages.get(i);
16808 boolean childPackageDeleted = true;
16809 for (int j = 0; j < newChildCount; j++) {
16810 PackageParser.Package newChildPkg = pkg.childPackages.get(j);
16811 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16812 childPackageDeleted = false;
16816 if (childPackageDeleted) {
16817 PackageSetting ps1 = mSettings.getDisabledSystemPkgLPr(
16818 deletedChildPkg.packageName);
16819 if (ps1 != null && res.removedInfo.removedChildPackages != null) {
16820 PackageRemovedInfo removedChildRes = res.removedInfo
16821 .removedChildPackages.get(deletedChildPkg.packageName);
16822 removePackageDataLIF(ps1, request.mAllUsers, removedChildRes, 0,
16824 removedChildRes.removedForAllUsers = mPackages.get(ps1.name)
16831 executeDeletePackageLIF(reconciledPkg.deletePackageAction, packageName,
16832 true, request.mAllUsers, true, pkg);
16833 } catch (SystemDeleteException e) {
16834 if (Build.IS_ENG) {
16835 throw new RuntimeException("Unexpected failure", e);
16836 // ignore; not possible for non-system app
16839 // Successfully deleted the old package; proceed with replace.
16841 // If deleted package lived in a container, give users a chance to
16842 // relinquish resources before killing.
16843 if (oldPackage.isForwardLocked() || isExternal(oldPackage)) {
16844 if (DEBUG_INSTALL) {
16845 Slog.i(TAG, "upgrading pkg " + oldPackage
16846 + " is ASEC-hosted -> UNAVAILABLE");
16848 final int[] uidArray = new int[]{oldPackage.applicationInfo.uid};
16849 final ArrayList<String> pkgList = new ArrayList<>(1);
16850 pkgList.add(oldPackage.applicationInfo.packageName);
16851 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16854 // Update the in-memory copy of the previous code paths.
16855 PackageSetting ps1 = mSettings.mPackages.get(
16856 reconciledPkg.prepareResult.existingPackage.packageName);
16857 if ((reconciledPkg.installArgs.installFlags & PackageManager.DONT_KILL_APP)
16859 if (ps1.mOldCodePaths == null) {
16860 ps1.mOldCodePaths = new ArraySet<>();
16862 Collections.addAll(ps1.mOldCodePaths, oldPackage.baseCodePath);
16863 if (oldPackage.splitCodePaths != null) {
16864 Collections.addAll(ps1.mOldCodePaths, oldPackage.splitCodePaths);
16867 ps1.mOldCodePaths = null;
16869 if (ps1.childPackageNames != null) {
16870 for (int i = ps1.childPackageNames.size() - 1; i >= 0; --i) {
16871 final String childPkgName = ps1.childPackageNames.get(i);
16872 final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
16873 childPs.mOldCodePaths = ps1.mOldCodePaths;
16877 if (reconciledPkg.installResult.returnCode
16878 == PackageManager.INSTALL_SUCCEEDED) {
16879 PackageSetting ps2 = mSettings.getPackageLPr(pkg.packageName);
16881 res.removedInfo.removedForAllUsers = mPackages.get(ps2.name) == null;
16882 if (res.removedInfo.removedChildPackages != null) {
16883 final int childCount1 = res.removedInfo.removedChildPackages.size();
16884 // Iterate in reverse as we may modify the collection
16885 for (int i = childCount1 - 1; i >= 0; i--) {
16886 String childPackageName =
16887 res.removedInfo.removedChildPackages.keyAt(i);
16888 if (res.addedChildPackages.containsKey(childPackageName)) {
16889 res.removedInfo.removedChildPackages.removeAt(i);
16891 PackageRemovedInfo childInfo = res.removedInfo
16892 .removedChildPackages.valueAt(i);
16893 childInfo.removedForAllUsers = mPackages.get(
16894 childInfo.removedPackage) == null;
16903 commitReconciledScanResultLocked(reconciledPkg);
16904 updateSettingsLI(pkg, reconciledPkg.installArgs.installerPackageName, request.mAllUsers,
16905 res, reconciledPkg.installArgs.user, reconciledPkg.installArgs.installReason);
16907 final PackageSetting ps = mSettings.mPackages.get(packageName);
16909 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
16910 ps.setUpdateAvailable(false /*updateAvailable*/);
16912 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16913 for (int i = 0; i < childCount; i++) {
16914 PackageParser.Package childPkg = pkg.childPackages.get(i);
16915 PackageInstalledInfo childRes = res.addedChildPackages.get(
16916 childPkg.packageName);
16917 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16918 if (childPs != null) {
16919 childRes.newUsers = childPs.queryInstalledUsers(
16920 sUserManager.getUserIds(), true);
16923 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16924 updateSequenceNumberLP(ps, res.newUsers);
16925 updateInstantAppInstallerLocked(packageName);
16931 * Installs one or more packages atomically. This operation is broken up into four phases:
16933 * <li><b>Prepare</b>
16934 * <br/>Analyzes any current install state, parses the package and does initial
16935 * validation on it.</li>
16937 * <br/>Interrogates the parsed packages given the context collected in prepare.</li>
16938 * <li><b>Reconcile</b>
16939 * <br/>Validates scanned packages in the context of each other and the current system
16940 * state to ensure that the install will be successful.
16941 * <li><b>Commit</b>
16942 * <br/>Commits all scanned packages and updates system state. This is the only place
16943 * that system state may be modified in the install flow and all predictable errors
16944 * must be determined before this phase.</li>
16947 * Failure at any phase will result in a full failure to install all packages.
16949 @GuardedBy("mInstallLock")
16950 private void installPackagesLI(List<InstallRequest> requests) {
16951 final Map<String, ScanResult> preparedScans = new ArrayMap<>(requests.size());
16952 final Map<String, InstallArgs> installArgs = new ArrayMap<>(requests.size());
16953 final Map<String, PackageInstalledInfo> installResults = new ArrayMap<>(requests.size());
16954 final Map<String, PrepareResult> prepareResults = new ArrayMap<>(requests.size());
16955 final Map<String, VersionInfo> versionInfos = new ArrayMap<>(requests.size());
16956 final Map<String, PackageSetting> lastStaticSharedLibSettings =
16957 new ArrayMap<>(requests.size());
16958 final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size());
16959 boolean success = false;
16961 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackagesLI");
16962 for (InstallRequest request : requests) {
16963 // TODO(b/109941548): remove this once we've pulled everything from it and into
16964 // scan, reconcile or commit.
16965 final PrepareResult prepareResult;
16967 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage");
16968 prepareResult = preparePackageLI(request.args, request.installResult);
16969 } catch (PrepareFailure prepareFailure) {
16970 request.installResult.setError(prepareFailure.error,
16971 prepareFailure.getMessage());
16972 request.installResult.origPackage = prepareFailure.conflictingPackage;
16973 request.installResult.origPermission = prepareFailure.conflictingPermission;
16976 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16978 request.installResult.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16979 request.installResult.installerPackageName = request.args.installerPackageName;
16981 final String packageName = prepareResult.packageToScan.packageName;
16982 prepareResults.put(packageName, prepareResult);
16983 installResults.put(packageName, request.installResult);
16984 installArgs.put(packageName, request.args);
16986 final List<ScanResult> scanResults = scanPackageTracedLI(
16987 prepareResult.packageToScan, prepareResult.parseFlags,
16988 prepareResult.scanFlags, System.currentTimeMillis(),
16989 request.args.user);
16990 for (ScanResult result : scanResults) {
16991 if (null != preparedScans.put(result.pkgSetting.pkg.packageName, result)) {
16992 request.installResult.setError(
16993 PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE,
16994 "Duplicate package " + result.pkgSetting.pkg.packageName
16995 + " in multi-package install request.");
16998 createdAppId.put(packageName, optimisticallyRegisterAppId(result));
16999 versionInfos.put(result.pkgSetting.pkg.packageName,
17000 getSettingsVersionForPackage(result.pkgSetting.pkg));
17001 if (result.staticSharedLibraryInfo != null) {
17002 final PackageSetting sharedLibLatestVersionSetting =
17003 getSharedLibLatestVersionSetting(result);
17004 if (sharedLibLatestVersionSetting != null) {
17005 lastStaticSharedLibSettings.put(result.pkgSetting.pkg.packageName,
17006 sharedLibLatestVersionSetting);
17010 } catch (PackageManagerException e) {
17011 request.installResult.setError("Scanning Failed.", e);
17015 ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs,
17019 Collections.unmodifiableMap(mPackages), versionInfos,
17020 lastStaticSharedLibSettings);
17021 CommitRequest commitRequest = null;
17022 synchronized (mPackages) {
17023 Map<String, ReconciledPackage> reconciledPackages;
17025 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages");
17026 reconciledPackages = reconcilePackagesLocked(
17027 reconcileRequest, mSettings.mKeySetManagerService);
17028 } catch (ReconcileFailure e) {
17029 for (InstallRequest request : requests) {
17030 request.installResult.setError("Reconciliation failed...", e);
17034 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17037 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "commitPackages");
17038 commitRequest = new CommitRequest(reconciledPackages,
17039 sUserManager.getUserIds());
17040 commitPackagesLocked(commitRequest);
17043 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17046 executePostCommitSteps(commitRequest);
17049 for (ScanResult result : preparedScans.values()) {
17050 if (createdAppId.getOrDefault(result.request.pkg.packageName, false)) {
17051 cleanUpAppIdCreation(result);
17054 // TODO(patb): create a more descriptive reason than unknown in future release
17055 // mark all non-failure installs as UNKNOWN so we do not treat them as success
17056 for (InstallRequest request : requests) {
17057 if (request.installResult.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17058 request.installResult.returnCode = PackageManager.INSTALL_UNKNOWN;
17062 for (PrepareResult result : prepareResults.values()) {
17063 if (result.freezer != null) {
17064 result.freezer.close();
17067 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17072 * On successful install, executes remaining steps after commit completes and the package lock
17073 * is released. These are typically more expensive or require calls to installd, which often
17074 * locks on {@link #mPackages}.
17076 private void executePostCommitSteps(CommitRequest commitRequest) {
17077 for (ReconciledPackage reconciledPkg : commitRequest.reconciledPackages.values()) {
17078 final boolean instantApp = ((reconciledPkg.scanResult.request.scanFlags
17079 & PackageManagerService.SCAN_AS_INSTANT_APP) != 0);
17080 final PackageParser.Package pkg = reconciledPkg.pkgSetting.pkg;
17081 final String packageName = pkg.packageName;
17082 prepareAppDataAfterInstallLIF(pkg);
17083 if (reconciledPkg.prepareResult.clearCodeCache) {
17084 clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
17085 | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
17087 if (reconciledPkg.prepareResult.replace) {
17088 mDexManager.notifyPackageUpdated(pkg.packageName,
17089 pkg.baseCodePath, pkg.splitCodePaths);
17092 // Prepare the application profiles for the new code paths.
17093 // This needs to be done before invoking dexopt so that any install-time profile
17094 // can be used for optimizations.
17095 mArtManagerService.prepareAppProfiles(
17097 resolveUserIds(reconciledPkg.installArgs.user.getIdentifier()),
17098 /* updateReferenceProfileContent= */ true);
17100 // Check whether we need to dexopt the app.
17102 // NOTE: it is IMPORTANT to call dexopt:
17103 // - after doRename which will sync the package data from PackageParser.Package and
17104 // its corresponding ApplicationInfo.
17105 // - after installNewPackageLIF or replacePackageLIF which will update result with the
17106 // uid of the application (pkg.applicationInfo.uid).
17107 // This update happens in place!
17109 // We only need to dexopt if the package meets ALL of the following conditions:
17110 // 1) it is not an instant app or if it is then dexopt is enabled via gservices.
17111 // 2) it is not debuggable.
17113 // Note that we do not dexopt instant apps by default. dexopt can take some time to
17114 // complete, so we skip this step during installation. Instead, we'll take extra time
17115 // the first time the instant app starts. It's preferred to do it this way to provide
17116 // continuous progress to the useur instead of mysteriously blocking somewhere in the
17117 // middle of running an instant app. The default behaviour can be overridden
17119 final boolean performDexopt =
17120 (!instantApp || Global.getInt(mContext.getContentResolver(),
17121 Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
17122 && ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0);
17124 if (performDexopt) {
17125 // Compile the layout resources.
17126 if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
17127 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "compileLayouts");
17128 mViewCompiler.compileLayouts(pkg);
17129 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17132 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
17133 // Do not run PackageDexOptimizer through the local performDexOpt
17134 // method because `pkg` may not be in `mPackages` yet.
17136 // Also, don't fail application installs if the dexopt step fails.
17137 DexoptOptions dexoptOptions = new DexoptOptions(packageName,
17139 DexoptOptions.DEXOPT_BOOT_COMPLETE
17140 | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE);
17141 mPackageDexOptimizer.performDexOpt(pkg,
17142 null /* instructionSets */,
17143 getOrCreateCompilerPackageStats(pkg),
17144 mDexManager.getPackageUseInfoOrDefault(packageName),
17146 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17149 // Notify BackgroundDexOptService that the package has been changed.
17150 // If this is an update of a package which used to fail to compile,
17151 // BackgroundDexOptService will remove it from its blacklist.
17152 // TODO: Layering violation
17153 BackgroundDexOptService.notifyPackageChanged(packageName);
17158 * The set of data needed to successfully install the prepared package. This includes data that
17159 * will be used to scan and reconcile the package.
17161 private static class PrepareResult {
17162 public final int installReason;
17163 public final String volumeUuid;
17164 public final String installerPackageName;
17165 public final UserHandle user;
17166 public final boolean replace;
17167 public final int scanFlags;
17168 public final int parseFlags;
17169 @Nullable /* The original Package if it is being replaced, otherwise {@code null} */
17170 public final PackageParser.Package existingPackage;
17171 public final PackageParser.Package packageToScan;
17172 public final boolean clearCodeCache;
17173 public final boolean system;
17174 /* The original package name if it was changed during an update, otherwise {@code null}. */
17176 public final String renamedPackage;
17177 public final PackageFreezer freezer;
17178 public final PackageSetting originalPs;
17179 public final PackageSetting disabledPs;
17180 public final PackageSetting[] childPackageSettings;
17182 private PrepareResult(int installReason, String volumeUuid,
17183 String installerPackageName, UserHandle user, boolean replace, int scanFlags,
17184 int parseFlags, PackageParser.Package existingPackage,
17185 PackageParser.Package packageToScan, boolean clearCodeCache, boolean system,
17186 String renamedPackage, PackageFreezer freezer, PackageSetting originalPs,
17187 PackageSetting disabledPs, PackageSetting[] childPackageSettings) {
17188 this.installReason = installReason;
17189 this.volumeUuid = volumeUuid;
17190 this.installerPackageName = installerPackageName;
17192 this.replace = replace;
17193 this.scanFlags = scanFlags;
17194 this.parseFlags = parseFlags;
17195 this.existingPackage = existingPackage;
17196 this.packageToScan = packageToScan;
17197 this.clearCodeCache = clearCodeCache;
17198 this.system = system;
17199 this.renamedPackage = renamedPackage;
17200 this.freezer = freezer;
17201 this.originalPs = originalPs;
17202 this.disabledPs = disabledPs;
17203 this.childPackageSettings = childPackageSettings;
17207 private static class PrepareFailure extends PackageManagerException {
17209 public String conflictingPackage;
17210 public String conflictingPermission;
17212 PrepareFailure(int error) {
17213 super(error, "Failed to prepare for install.");
17216 PrepareFailure(int error, String detailMessage) {
17217 super(error, detailMessage);
17220 PrepareFailure(String message, Exception e) {
17221 super(e instanceof PackageParserException
17222 ? ((PackageParserException) e).error
17223 : ((PackageManagerException) e).error,
17224 ExceptionUtils.getCompleteMessage(message, e));
17227 PrepareFailure conflictsWithExistingPermission(String conflictingPermission,
17228 String conflictingPackage) {
17229 this.conflictingPermission = conflictingPermission;
17230 this.conflictingPackage = conflictingPackage;
17235 @GuardedBy("mInstallLock")
17236 private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res)
17237 throws PrepareFailure {
17238 final int installFlags = args.installFlags;
17239 final String installerPackageName = args.installerPackageName;
17240 final String volumeUuid = args.volumeUuid;
17241 final File tmpPackageFile = new File(args.getCodePath());
17242 final boolean onExternal = args.volumeUuid != null;
17243 final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
17244 final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
17245 final boolean virtualPreload =
17246 ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
17247 @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
17248 if (args.move != null) {
17249 // moving a complete application; perform an initial scan on the new install location
17250 scanFlags |= SCAN_INITIAL;
17252 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
17253 scanFlags |= SCAN_DONT_KILL_APP;
17256 scanFlags |= SCAN_AS_INSTANT_APP;
17259 scanFlags |= SCAN_AS_FULL_APP;
17261 if (virtualPreload) {
17262 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
17265 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
17268 if (instantApp && onExternal) {
17269 Slog.i(TAG, "Incompatible ephemeral install; external=" + onExternal);
17270 throw new PrepareFailure(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17273 // Retrieve PackageSettings and parse package
17274 @ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
17275 | PackageParser.PARSE_ENFORCE_CODE
17276 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
17278 PackageParser pp = new PackageParser();
17279 pp.setSeparateProcesses(mSeparateProcesses);
17280 pp.setDisplayMetrics(mMetrics);
17281 pp.setCallback(mPackageParserCallback);
17283 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
17284 final PackageParser.Package pkg;
17286 pkg = pp.parsePackage(tmpPackageFile, parseFlags);
17287 DexMetadataHelper.validatePackageDexMetadata(pkg);
17288 } catch (PackageParserException e) {
17289 throw new PrepareFailure("Failed parse during installPackageLI", e);
17291 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17294 // Instant apps have several additional install-time checks.
17296 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
17298 "Instant app package " + pkg.packageName + " does not target at least O");
17299 throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
17300 "Instant app package must target at least O");
17302 if (pkg.mSharedUserId != null) {
17303 Slog.w(TAG, "Instant app package " + pkg.packageName
17304 + " may not declare sharedUserId.");
17305 throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
17306 "Instant app package may not declare a sharedUserId");
17310 if (pkg.applicationInfo.isStaticSharedLibrary()) {
17311 // Static shared libraries have synthetic package names
17312 renameStaticSharedLibraryPackage(pkg);
17314 // No static shared libs on external storage
17316 Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
17317 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17318 "Packages declaring static-shared libs cannot be updated");
17322 // If we are installing a clustered package add results for the children
17323 if (pkg.childPackages != null) {
17324 synchronized (mPackages) {
17325 final int childCount = pkg.childPackages.size();
17326 for (int i = 0; i < childCount; i++) {
17327 PackageParser.Package childPkg = pkg.childPackages.get(i);
17328 PackageInstalledInfo childRes = new PackageInstalledInfo();
17329 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17330 childRes.pkg = childPkg;
17331 childRes.name = childPkg.packageName;
17332 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17333 if (childPs != null) {
17334 childRes.origUsers = childPs.queryInstalledUsers(
17335 sUserManager.getUserIds(), true);
17337 if ((mPackages.containsKey(childPkg.packageName))) {
17338 childRes.removedInfo = new PackageRemovedInfo(this);
17339 childRes.removedInfo.removedPackage = childPkg.packageName;
17340 childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17342 if (res.addedChildPackages == null) {
17343 res.addedChildPackages = new ArrayMap<>();
17345 res.addedChildPackages.put(childPkg.packageName, childRes);
17350 // If package doesn't declare API override, mark that we have an install
17351 // time CPU ABI override.
17352 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
17353 pkg.cpuAbiOverride = args.abiOverride;
17356 String pkgName = res.name = pkg.packageName;
17357 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_TEST_ONLY) != 0) {
17358 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
17359 throw new PrepareFailure(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
17364 // either use what we've been given or parse directly from the APK
17365 if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
17366 pkg.setSigningDetails(args.signingDetails);
17368 PackageParser.collectCertificates(pkg, false /* skipVerify */);
17370 } catch (PackageParserException e) {
17371 throw new PrepareFailure("Failed collect during installPackageLI", e);
17374 if (instantApp && pkg.mSigningDetails.signatureSchemeVersion
17375 < SignatureSchemeVersion.SIGNING_BLOCK_V2) {
17376 Slog.w(TAG, "Instant app package " + pkg.packageName
17377 + " is not signed with at least APK Signature Scheme v2");
17378 throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
17379 "Instant app package must be signed with APK Signature Scheme v2 or greater");
17382 // Get rid of all references to package scan path via parser.
17384 boolean systemApp = false;
17385 boolean replace = false;
17386 synchronized (mPackages) {
17387 // Check if installing already existing package
17388 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
17389 String oldName = mSettings.getRenamedPackageLPr(pkgName);
17390 if (pkg.mOriginalPackages != null
17391 && pkg.mOriginalPackages.contains(oldName)
17392 && mPackages.containsKey(oldName)) {
17393 // This package is derived from an original package,
17394 // and this device has been updating from that original
17395 // name. We must continue using the original name, so
17396 // rename the new package here.
17397 pkg.setPackageName(oldName);
17398 pkgName = pkg.packageName;
17400 if (DEBUG_INSTALL) {
17401 Slog.d(TAG, "Replacing existing renamed package: oldName="
17402 + oldName + " pkgName=" + pkgName);
17404 } else if (mPackages.containsKey(pkgName)) {
17405 // This package, under its official name, already exists
17406 // on the device; we should replace it.
17408 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
17411 // Child packages are installed through the parent package
17412 if (pkg.parentPackage != null) {
17413 throw new PrepareFailure(
17414 PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
17415 "Package " + pkg.packageName + " is child of package "
17416 + pkg.parentPackage.parentPackage + ". Child packages "
17417 + "can be updated only through the parent package.");
17421 // Prevent apps opting out from runtime permissions
17422 PackageParser.Package oldPackage = mPackages.get(pkgName);
17423 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
17424 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
17425 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
17426 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
17427 throw new PrepareFailure(
17428 PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
17429 "Package " + pkg.packageName + " new target SDK " + newTargetSdk
17430 + " doesn't support runtime permissions but the old"
17431 + " target SDK " + oldTargetSdk + " does.");
17433 // Prevent persistent apps from being updated
17434 if (((oldPackage.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0)
17435 && ((installFlags & PackageManager.INSTALL_STAGED) == 0)) {
17436 throw new PrepareFailure(PackageManager.INSTALL_FAILED_INVALID_APK,
17437 "Package " + oldPackage.packageName + " is a persistent app. "
17438 + "Persistent apps are not updateable.");
17440 // Prevent installing of child packages
17441 if (oldPackage.parentPackage != null) {
17442 throw new PrepareFailure(
17443 PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
17444 "Package " + pkg.packageName + " is child of package "
17445 + oldPackage.parentPackage + ". Child packages "
17446 + "can be updated only through the parent package.");
17451 PackageSetting ps = mSettings.mPackages.get(pkgName);
17453 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
17455 // Static shared libs have same package with different versions where
17456 // we internally use a synthetic package name to allow multiple versions
17457 // of the same package, therefore we need to compare signatures against
17458 // the package setting for the latest library version.
17459 PackageSetting signatureCheckPs = ps;
17460 if (pkg.applicationInfo.isStaticSharedLibrary()) {
17461 SharedLibraryInfo libraryInfo = getLatestSharedLibraVersionLPr(pkg);
17462 if (libraryInfo != null) {
17463 signatureCheckPs = mSettings.getPackageLPr(libraryInfo.getPackageName());
17467 // Quick sanity check that we're signed correctly if updating;
17468 // we'll check this again later when scanning, but we want to
17469 // bail early here before tripping over redefined permissions.
17470 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
17471 if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
17472 if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
17473 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
17474 + pkg.packageName + " upgrade keys do not match the "
17475 + "previously installed version");
17479 final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
17480 final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
17481 // We don't care about disabledPkgSetting on install for now.
17482 final boolean compatMatch = verifySignatures(
17483 signatureCheckPs, null, pkg.mSigningDetails, compareCompat,
17485 // The new KeySets will be re-added later in the scanning process.
17487 synchronized (mPackages) {
17488 ksms.removeAppKeySetDataLPw(pkg.packageName);
17491 } catch (PackageManagerException e) {
17492 throw new PrepareFailure(e.error, e.getMessage());
17496 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
17497 systemApp = (ps.pkg.applicationInfo.flags &
17498 ApplicationInfo.FLAG_SYSTEM) != 0;
17500 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17504 int N = pkg.permissions.size();
17505 for (int i = N - 1; i >= 0; i--) {
17506 final PackageParser.Permission perm = pkg.permissions.get(i);
17507 final BasePermission bp =
17508 (BasePermission) mPermissionManager.getPermissionTEMP(perm.info.name);
17510 // Don't allow anyone but the system to define ephemeral permissions.
17511 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
17513 Slog.w(TAG, "Non-System package " + pkg.packageName
17514 + " attempting to delcare ephemeral permission "
17515 + perm.info.name + "; Removing ephemeral.");
17516 perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
17519 // Check whether the newly-scanned package wants to define an already-defined perm
17521 // If the defining package is signed with our cert, it's okay. This
17522 // also includes the "updating the same package" case, of course.
17523 // "updating same package" could also involve key-rotation.
17524 final boolean sigsOk;
17525 final String sourcePackageName = bp.getSourcePackageName();
17526 final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
17527 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
17528 if (sourcePackageName.equals(pkg.packageName)
17529 && (ksms.shouldCheckUpgradeKeySetLocked(
17530 sourcePackageSetting, scanFlags))) {
17531 sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, pkg);
17534 // in the event of signing certificate rotation, we need to see if the
17535 // package's certificate has rotated from the current one, or if it is an
17536 // older certificate with which the current is ok with sharing permissions
17537 if (sourcePackageSetting.signatures.mSigningDetails.checkCapability(
17538 pkg.mSigningDetails,
17539 PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
17541 } else if (pkg.mSigningDetails.checkCapability(
17542 sourcePackageSetting.signatures.mSigningDetails,
17543 PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
17545 // the scanned package checks out, has signing certificate rotation
17546 // history, and is newer; bring it over
17547 sourcePackageSetting.signatures.mSigningDetails = pkg.mSigningDetails;
17554 // If the owning package is the system itself, we log but allow
17555 // install to proceed; we fail the install on all other permission
17557 if (!sourcePackageName.equals("android")) {
17558 throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
17560 + " attempting to redeclare permission "
17561 + perm.info.name + " already owned by "
17562 + sourcePackageName)
17563 .conflictsWithExistingPermission(perm.info.name,
17564 sourcePackageName);
17566 Slog.w(TAG, "Package " + pkg.packageName
17567 + " attempting to redeclare system permission "
17568 + perm.info.name + "; ignoring new declaration");
17569 pkg.permissions.remove(i);
17571 } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17572 // Prevent apps to change protection level to dangerous from any other
17573 // type as this would allow a privilege escalation where an app adds a
17574 // normal/signature permission in other app's group and later redefines
17575 // it as dangerous leading to the group auto-grant.
17576 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
17577 == PermissionInfo.PROTECTION_DANGEROUS) {
17578 if (bp != null && !bp.isRuntime()) {
17579 Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
17580 + "non-runtime permission " + perm.info.name
17581 + " to runtime; keeping old protection level");
17582 perm.info.protectionLevel = bp.getProtectionLevel();
17592 // Abort update; system app can't be replaced with app on sdcard
17593 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17594 "Cannot install updates to system apps on sdcard");
17595 } else if (instantApp) {
17596 // Abort update; system app can't be replaced with an instant app
17597 throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
17598 "Cannot update a system app with an instant app");
17602 if (args.move != null) {
17603 // We did an in-place move, so dex is ready to roll
17604 scanFlags |= SCAN_NO_DEX;
17605 scanFlags |= SCAN_MOVE;
17607 synchronized (mPackages) {
17608 final PackageSetting ps = mSettings.mPackages.get(pkgName);
17610 res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17611 "Missing settings for moved package " + pkgName);
17614 // We moved the entire application as-is, so bring over the
17615 // previously derived ABI information.
17616 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
17617 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
17621 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
17622 scanFlags |= SCAN_NO_DEX;
17625 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
17626 args.abiOverride : pkg.cpuAbiOverride);
17627 final boolean extractNativeLibs = !pkg.isLibrary();
17628 derivePackageAbi(pkg, abiOverride, extractNativeLibs);
17629 } catch (PackageManagerException pme) {
17630 Slog.e(TAG, "Error deriving application ABI", pme);
17631 throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
17632 "Error deriving application ABI");
17636 if (!args.doRename(res.returnCode, pkg)) {
17637 throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
17641 setUpFsVerityIfPossible(pkg);
17642 } catch (InstallerException | IOException | DigestException | NoSuchAlgorithmException e) {
17643 throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
17644 "Failed to set up verity: " + e);
17648 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
17650 if (DEBUG_DOMAIN_VERIFICATION) {
17651 Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);
17654 final PackageFreezer freezer =
17655 freezePackageForInstall(pkgName, installFlags, "installPackageLI");
17656 boolean shouldCloseFreezerBeforeReturn = true;
17658 final PackageParser.Package existingPackage;
17659 String renamedPackage = null;
17660 boolean sysPkg = false;
17661 String targetVolumeUuid = volumeUuid;
17662 int targetScanFlags = scanFlags;
17663 int targetParseFlags = parseFlags;
17664 final PackageSetting ps;
17665 final PackageSetting disabledPs;
17666 final PackageSetting[] childPackages;
17668 targetVolumeUuid = null;
17669 if (pkg.applicationInfo.isStaticSharedLibrary()) {
17670 // Static libs have a synthetic package name containing the version
17671 // and cannot be updated as an update would get a new package name,
17672 // unless this is the exact same version code which is useful for
17674 PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
17675 if (existingPkg != null
17676 && existingPkg.getLongVersionCode() != pkg.getLongVersionCode()) {
17677 throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PACKAGE,
17678 "Packages declaring "
17679 + "static-shared libs cannot be updated");
17683 final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
17685 final PackageParser.Package oldPackage;
17686 final String pkgName11 = pkg.packageName;
17687 final int[] allUsers;
17688 final int[] installedUsers;
17690 synchronized (mPackages) {
17691 oldPackage = mPackages.get(pkgName11);
17692 existingPackage = oldPackage;
17693 if (DEBUG_INSTALL) {
17695 "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
17698 ps = mSettings.mPackages.get(pkgName11);
17699 disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
17701 // verify signatures are valid
17702 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
17703 if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
17704 if (!ksms.checkUpgradeKeySetLocked(ps, pkg)) {
17705 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17706 "New package not signed by keys specified by upgrade-keysets: "
17710 // default to original signature matching
17711 if (!pkg.mSigningDetails.checkCapability(oldPackage.mSigningDetails,
17712 SigningDetails.CertCapabilities.INSTALLED_DATA)
17713 && !oldPackage.mSigningDetails.checkCapability(
17714 pkg.mSigningDetails,
17715 SigningDetails.CertCapabilities.ROLLBACK)) {
17716 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17717 "New package has a different signature: " + pkgName11);
17721 // don't allow a system upgrade unless the upgrade hash matches
17722 if (oldPackage.restrictUpdateHash != null && oldPackage.isSystem()) {
17723 final byte[] digestBytes;
17725 final MessageDigest digest = MessageDigest.getInstance("SHA-512");
17726 updateDigest(digest, new File(pkg.baseCodePath));
17727 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
17728 for (String path : pkg.splitCodePaths) {
17729 updateDigest(digest, new File(path));
17732 digestBytes = digest.digest();
17733 } catch (NoSuchAlgorithmException | IOException e) {
17734 throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
17735 "Could not compute hash: " + pkgName11);
17737 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
17738 throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
17739 "New package fails restrict-update check: " + pkgName11);
17741 // retain upgrade restriction
17742 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
17745 // Check for shared user id changes
17746 String invalidPackageName =
17747 getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
17748 if (invalidPackageName != null) {
17749 throw new PrepareFailure(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
17750 "Package " + invalidPackageName + " tried to change user "
17751 + oldPackage.mSharedUserId);
17754 // In case of rollback, remember per-user/profile install state
17755 allUsers = sUserManager.getUserIds();
17756 installedUsers = ps.queryInstalledUsers(allUsers, true);
17759 // don't allow an upgrade from full to ephemeral
17760 if (isInstantApp) {
17761 if (args.user == null || args.user.getIdentifier() == UserHandle.USER_ALL) {
17762 for (int currentUser : allUsers) {
17763 if (!ps.getInstantApp(currentUser)) {
17764 // can't downgrade from full to instant
17766 "Can't replace full app with instant app: " + pkgName11
17767 + " for user: " + currentUser);
17768 throw new PrepareFailure(
17769 PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17772 } else if (!ps.getInstantApp(args.user.getIdentifier())) {
17773 // can't downgrade from full to instant
17774 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName11
17775 + " for user: " + args.user.getIdentifier());
17776 throw new PrepareFailure(
17777 PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17782 // Update what is removed
17783 res.removedInfo = new PackageRemovedInfo(this);
17784 res.removedInfo.uid = oldPackage.applicationInfo.uid;
17785 res.removedInfo.removedPackage = oldPackage.packageName;
17786 res.removedInfo.installerPackageName = ps.installerPackageName;
17787 res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
17788 res.removedInfo.isUpdate = true;
17789 res.removedInfo.origUsers = installedUsers;
17790 res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
17791 for (int i = 0; i < installedUsers.length; i++) {
17792 final int userId = installedUsers[i];
17793 res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
17796 childPackages = mSettings.getChildSettingsLPr(ps);
17797 if (childPackages != null) {
17798 for (PackageSetting childPs : childPackages) {
17799 boolean childPackageUpdated = false;
17800 PackageParser.Package childPkg = (childPs == null) ? null : childPs.pkg;
17801 if (res.addedChildPackages != null) {
17802 PackageInstalledInfo childRes = res.addedChildPackages.get(
17803 childPkg.packageName);
17804 if (childRes != null) {
17805 childRes.removedInfo.uid = childPkg.applicationInfo.uid;
17806 childRes.removedInfo.removedPackage = childPkg.packageName;
17807 if (childPs != null) {
17808 childRes.removedInfo.installerPackageName =
17809 childPs.installerPackageName;
17811 childRes.removedInfo.isUpdate = true;
17812 childRes.removedInfo.installReasons =
17813 res.removedInfo.installReasons;
17814 childPackageUpdated = true;
17817 if (!childPackageUpdated) {
17818 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
17819 childRemovedRes.removedPackage = childPkg.packageName;
17820 if (childPs != null) {
17821 childRemovedRes.installerPackageName = childPs.installerPackageName;
17823 childRemovedRes.isUpdate = false;
17824 childRemovedRes.dataRemoved = true;
17825 synchronized (mPackages) {
17826 if (childPs != null) {
17827 childRemovedRes.origUsers = childPs.queryInstalledUsers(
17832 if (res.removedInfo.removedChildPackages == null) {
17833 res.removedInfo.removedChildPackages = new ArrayMap<>();
17835 res.removedInfo.removedChildPackages.put(childPkg.packageName,
17842 sysPkg = (isSystemApp(oldPackage));
17844 // Set the system/privileged/oem/vendor/product flags as needed
17845 final boolean privileged = isPrivilegedApp(oldPackage);
17846 final boolean oem = isOemApp(oldPackage);
17847 final boolean vendor = isVendorApp(oldPackage);
17848 final boolean product = isProductApp(oldPackage);
17849 final boolean odm = isOdmApp(oldPackage);
17850 final @ParseFlags int systemParseFlags = parseFlags;
17851 final @ScanFlags int systemScanFlags = scanFlags
17853 | (privileged ? SCAN_AS_PRIVILEGED : 0)
17854 | (oem ? SCAN_AS_OEM : 0)
17855 | (vendor ? SCAN_AS_VENDOR : 0)
17856 | (product ? SCAN_AS_PRODUCT : 0)
17857 | (odm ? SCAN_AS_ODM : 0);
17859 if (DEBUG_INSTALL) {
17860 Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
17861 + ", old=" + oldPackage);
17863 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17864 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
17865 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
17866 targetParseFlags = systemParseFlags;
17867 targetScanFlags = systemScanFlags;
17868 } else { // non system replace
17870 if (DEBUG_INSTALL) {
17872 "replaceNonSystemPackageLI: new=" + pkg + ", old="
17876 String pkgName1 = oldPackage.packageName;
17877 boolean deletedPkg = true;
17878 boolean addedPkg = false;
17879 boolean updatedSettings = false;
17881 final long origUpdateTime = (pkg.mExtras != null)
17882 ? ((PackageSetting) pkg.mExtras).lastUpdateTime : 0;
17885 } else { // new package install
17887 childPackages = null;
17890 existingPackage = null;
17891 // Remember this for later, in case we need to rollback this install
17892 String pkgName1 = pkg.packageName;
17894 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
17896 // TODO(patb): MOVE TO RECONCILE
17897 synchronized (mPackages) {
17898 renamedPackage = mSettings.getRenamedPackageLPr(pkgName1);
17899 if (renamedPackage != null) {
17900 // A package with the same name is already installed, though
17901 // it has been renamed to an older name. The package we
17902 // are trying to install should be installed as an update to
17903 // the existing one, but that has not been requested, so bail.
17904 throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS,
17905 "Attempt to re-install " + pkgName1
17906 + " without first uninstalling package running as "
17909 if (mPackages.containsKey(pkgName1)) {
17910 // Don't allow installation over an existing package with the same name.
17911 throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS,
17912 "Attempt to re-install " + pkgName1
17913 + " without first uninstalling.");
17917 // we're passing the freezer back to be closed in a later phase of install
17918 shouldCloseFreezerBeforeReturn = false;
17920 return new PrepareResult(args.installReason, targetVolumeUuid, installerPackageName,
17921 args.user, replace, targetScanFlags, targetParseFlags, existingPackage, pkg,
17922 replace /* clearCodeCache */, sysPkg, renamedPackage, freezer,
17923 ps, disabledPs, childPackages);
17925 if (shouldCloseFreezerBeforeReturn) {
17932 * Set up fs-verity for the given package if possible. This requires a feature flag of system
17933 * property to be enabled only if the kernel supports fs-verity.
17935 * <p>When the feature flag is set to legacy mode, only APK is supported (with some experimental
17936 * kernel patches). In normal mode, all file format can be supported.
17938 private void setUpFsVerityIfPossible(PackageParser.Package pkg) throws InstallerException,
17939 PrepareFailure, IOException, DigestException, NoSuchAlgorithmException {
17940 final boolean standardMode = PackageManagerServiceUtils.isApkVerityEnabled();
17941 final boolean legacyMode = PackageManagerServiceUtils.isLegacyApkVerityEnabled();
17942 if (!standardMode && !legacyMode) {
17946 // Collect files we care for fs-verity setup.
17947 ArrayMap<String, String> fsverityCandidates = new ArrayMap<>();
17949 synchronized (mPackages) {
17950 final PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
17951 if (ps != null && ps.isPrivileged()) {
17952 fsverityCandidates.put(pkg.baseCodePath, null);
17953 if (pkg.splitCodePaths != null) {
17954 for (String splitPath : pkg.splitCodePaths) {
17955 fsverityCandidates.put(splitPath, null);
17961 // NB: These files will become only accessible if the signing key is loaded in kernel's
17962 // .fs-verity keyring.
17963 fsverityCandidates.put(pkg.baseCodePath,
17964 VerityUtils.getFsveritySignatureFilePath(pkg.baseCodePath));
17966 final String dmPath = DexMetadataHelper.buildDexMetadataPathForApk(pkg.baseCodePath);
17967 if (new File(dmPath).exists()) {
17968 fsverityCandidates.put(dmPath, VerityUtils.getFsveritySignatureFilePath(dmPath));
17971 if (pkg.splitCodePaths != null) {
17972 for (String path : pkg.splitCodePaths) {
17973 fsverityCandidates.put(path, VerityUtils.getFsveritySignatureFilePath(path));
17975 final String splitDmPath = DexMetadataHelper.buildDexMetadataPathForApk(path);
17976 if (new File(splitDmPath).exists()) {
17977 fsverityCandidates.put(splitDmPath,
17978 VerityUtils.getFsveritySignatureFilePath(splitDmPath));
17984 for (Map.Entry<String, String> entry : fsverityCandidates.entrySet()) {
17985 final String filePath = entry.getKey();
17986 final String signaturePath = entry.getValue();
17989 // fs-verity is optional for now. Only set up if signature is provided.
17990 if (new File(signaturePath).exists() && !VerityUtils.hasFsverity(filePath)) {
17992 VerityUtils.setUpFsverity(filePath, signaturePath);
17993 } catch (IOException | DigestException | NoSuchAlgorithmException
17994 | SecurityException e) {
17995 throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
17996 "Failed to enable fs-verity: " + e);
18002 // In legacy mode, fs-verity can only be enabled by process with CAP_SYS_ADMIN.
18003 final VerityUtils.SetupResult result = VerityUtils.generateApkVeritySetupData(filePath);
18004 if (result.isOk()) {
18005 if (Build.IS_DEBUGGABLE) Slog.i(TAG, "Enabling verity to " + filePath);
18006 final FileDescriptor fd = result.getUnownedFileDescriptor();
18008 final byte[] rootHash = VerityUtils.generateApkVerityRootHash(filePath);
18010 // A file may already have fs-verity, e.g. when reused during a split
18011 // install. If the measurement succeeds, no need to attempt to set up.
18012 mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
18013 } catch (InstallerException e) {
18014 mInstaller.installApkVerity(filePath, fd, result.getContentSize());
18015 mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
18018 IoUtils.closeQuietly(fd);
18020 } else if (result.isFailed()) {
18021 throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
18022 "Failed to generate verity");
18027 private void startIntentFilterVerifications(int userId, boolean replacing,
18028 PackageParser.Package pkg) {
18029 if (mIntentFilterVerifierComponent == null) {
18030 Slog.w(TAG, "No IntentFilter verification will not be done as "
18031 + "there is no IntentFilterVerifier available!");
18035 final int verifierUid = getPackageUid(
18036 mIntentFilterVerifierComponent.getPackageName(),
18037 MATCH_DEBUG_TRIAGED_MISSING,
18038 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
18040 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
18041 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
18042 mHandler.sendMessage(msg);
18044 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18045 for (int i = 0; i < childCount; i++) {
18046 PackageParser.Package childPkg = pkg.childPackages.get(i);
18047 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
18048 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
18049 mHandler.sendMessage(msg);
18053 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
18054 PackageParser.Package pkg) {
18055 int size = pkg.activities.size();
18057 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18058 "No activity, so no need to verify any IntentFilter!");
18062 final boolean hasDomainURLs = hasDomainURLs(pkg);
18063 if (!hasDomainURLs) {
18064 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18065 "No domain URLs, so no need to verify any IntentFilter!");
18069 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
18070 + " if any IntentFilter from the " + size
18071 + " Activities needs verification ...");
18074 final String packageName = pkg.packageName;
18076 synchronized (mPackages) {
18077 // If this is a new install and we see that we've already run verification for this
18078 // package, we have nothing to do: it means the state was restored from backup.
18080 IntentFilterVerificationInfo ivi =
18081 mSettings.getIntentFilterVerificationLPr(packageName);
18083 if (DEBUG_DOMAIN_VERIFICATION) {
18084 Slog.i(TAG, "Package " + packageName+ " already verified: status="
18085 + ivi.getStatusString());
18091 // If any filters need to be verified, then all need to be.
18092 boolean needToVerify = false;
18093 for (PackageParser.Activity a : pkg.activities) {
18094 for (ActivityIntentInfo filter : a.intents) {
18095 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
18096 if (DEBUG_DOMAIN_VERIFICATION) {
18098 "Intent filter needs verification, so processing all filters");
18100 needToVerify = true;
18106 if (needToVerify) {
18107 final int verificationId = mIntentFilterVerificationToken++;
18108 for (PackageParser.Activity a : pkg.activities) {
18109 for (ActivityIntentInfo filter : a.intents) {
18110 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
18111 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18112 "Verification needed for IntentFilter:" + filter.toString());
18113 mIntentFilterVerifier.addOneIntentFilterVerification(
18114 verifierUid, userId, verificationId, filter, packageName);
18123 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
18124 + " IntentFilter verification" + (count > 1 ? "s" : "")
18125 + " for userId:" + userId);
18126 mIntentFilterVerifier.startVerifications(userId);
18128 if (DEBUG_DOMAIN_VERIFICATION) {
18129 Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
18134 @GuardedBy("mPackages")
18135 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
18136 final ComponentName cn = filter.activity.getComponentName();
18137 final String packageName = cn.getPackageName();
18139 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
18144 int status = ivi.getStatus();
18146 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
18147 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
18148 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
18157 private static boolean isMultiArch(ApplicationInfo info) {
18158 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
18161 private static boolean isExternal(PackageParser.Package pkg) {
18162 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
18165 private static boolean isExternal(PackageSetting ps) {
18166 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
18169 private static boolean isSystemApp(PackageParser.Package pkg) {
18170 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
18173 private static boolean isPrivilegedApp(PackageParser.Package pkg) {
18174 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
18177 private static boolean isOemApp(PackageParser.Package pkg) {
18178 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
18181 private static boolean isVendorApp(PackageParser.Package pkg) {
18182 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
18185 private static boolean isProductApp(PackageParser.Package pkg) {
18186 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
18189 private static boolean isProductServicesApp(PackageParser.Package pkg) {
18190 return (pkg.applicationInfo.privateFlags
18191 & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
18194 private static boolean isOdmApp(PackageParser.Package pkg) {
18195 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_ODM) != 0;
18198 private static boolean hasDomainURLs(PackageParser.Package pkg) {
18199 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
18202 private static boolean isSystemApp(PackageSetting ps) {
18203 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
18206 private static boolean isUpdatedSystemApp(PackageSetting ps) {
18207 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
18210 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
18211 if (isExternal(pkg)) {
18212 if (TextUtils.isEmpty(pkg.volumeUuid)) {
18213 return mSettings.getExternalVersion();
18215 return mSettings.findOrCreateVersion(pkg.volumeUuid);
18218 return mSettings.getInternalVersion();
18222 private void deleteTempPackageFiles() {
18223 final FilenameFilter filter =
18224 (dir, name) -> name.startsWith("vmdl") && name.endsWith(".tmp");
18228 public void deletePackageAsUser(String packageName, int versionCode,
18229 IPackageDeleteObserver observer, int userId, int flags) {
18230 deletePackageVersioned(new VersionedPackage(packageName, versionCode),
18231 new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
18235 public void deletePackageVersioned(VersionedPackage versionedPackage,
18236 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
18237 final int callingUid = Binder.getCallingUid();
18238 mContext.enforceCallingOrSelfPermission(
18239 android.Manifest.permission.DELETE_PACKAGES, null);
18240 final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
18241 Preconditions.checkNotNull(versionedPackage);
18242 Preconditions.checkNotNull(observer);
18243 Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
18244 PackageManager.VERSION_CODE_HIGHEST,
18245 Long.MAX_VALUE, "versionCode must be >= -1");
18247 final String packageName = versionedPackage.getPackageName();
18248 final long versionCode = versionedPackage.getLongVersionCode();
18249 final String internalPackageName;
18250 synchronized (mPackages) {
18251 // Normalize package name to handle renamed packages and static libs
18252 internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
18255 final int uid = Binder.getCallingUid();
18256 if (!isOrphaned(internalPackageName)
18257 && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
18258 mHandler.post(() -> {
18260 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
18261 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
18262 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
18263 observer.onUserActionRequired(intent);
18264 } catch (RemoteException re) {
18269 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
18270 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{userId};
18271 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
18272 mContext.enforceCallingOrSelfPermission(
18273 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
18274 "deletePackage for user " + userId);
18277 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
18278 mHandler.post(() -> {
18280 observer.onPackageDeleted(packageName,
18281 PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
18282 } catch (RemoteException re) {
18288 if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
18289 mHandler.post(() -> {
18291 observer.onPackageDeleted(packageName,
18292 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
18293 } catch (RemoteException re) {
18299 if (DEBUG_REMOVE) {
18300 Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
18301 + " deleteAllUsers: " + deleteAllUsers + " version="
18302 + (versionCode == PackageManager.VERSION_CODE_HIGHEST
18303 ? "VERSION_CODE_HIGHEST" : versionCode));
18305 // Queue up an async operation since the package deletion may take a little while.
18306 mHandler.post(() -> {
18308 final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
18309 boolean doDeletePackage = true;
18311 final boolean targetIsInstantApp =
18312 ps.getInstantApp(UserHandle.getUserId(callingUid));
18313 doDeletePackage = !targetIsInstantApp
18314 || canViewInstantApps;
18316 if (doDeletePackage) {
18317 if (!deleteAllUsers) {
18318 returnCode = deletePackageX(internalPackageName, versionCode,
18319 userId, deleteFlags);
18321 int[] blockUninstallUserIds = getBlockUninstallForUsers(
18322 internalPackageName, users);
18323 // If nobody is blocking uninstall, proceed with delete for all users
18324 if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
18325 returnCode = deletePackageX(internalPackageName, versionCode,
18326 userId, deleteFlags);
18328 // Otherwise uninstall individually for users with blockUninstalls=false
18329 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
18330 for (int userId1 : users) {
18331 if (!ArrayUtils.contains(blockUninstallUserIds, userId1)) {
18332 returnCode = deletePackageX(internalPackageName, versionCode,
18333 userId1, userFlags);
18334 if (returnCode != PackageManager.DELETE_SUCCEEDED) {
18335 Slog.w(TAG, "Package delete failed for user " + userId1
18336 + ", returnCode " + returnCode);
18340 // The app has only been marked uninstalled for certain users.
18341 // We still need to report that delete was blocked
18342 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
18346 returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18349 observer.onPackageDeleted(packageName, returnCode, null);
18350 } catch (RemoteException e) {
18351 Log.i(TAG, "Observer no longer exists.");
18356 private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
18357 if (pkg.staticSharedLibName != null) {
18358 return pkg.manifestPackageName;
18360 return pkg.packageName;
18363 @GuardedBy("mPackages")
18364 private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
18365 // Handle renamed packages
18366 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
18367 packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
18369 // Is this a static library?
18370 LongSparseArray<SharedLibraryInfo> versionedLib =
18371 mStaticLibsByDeclaringPackage.get(packageName);
18372 if (versionedLib == null || versionedLib.size() <= 0) {
18373 return packageName;
18376 // Figure out which lib versions the caller can see
18377 LongSparseLongArray versionsCallerCanSee = null;
18378 final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
18379 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
18380 && callingAppId != Process.ROOT_UID) {
18381 versionsCallerCanSee = new LongSparseLongArray();
18382 String libName = versionedLib.valueAt(0).getName();
18383 String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
18384 if (uidPackages != null) {
18385 for (String uidPackage : uidPackages) {
18386 PackageSetting ps = mSettings.getPackageLPr(uidPackage);
18387 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
18389 final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
18390 versionsCallerCanSee.append(libVersion, libVersion);
18396 // Caller can see nothing - done
18397 if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
18398 return packageName;
18401 // Find the version the caller can see and the app version code
18402 SharedLibraryInfo highestVersion = null;
18403 final int versionCount = versionedLib.size();
18404 for (int i = 0; i < versionCount; i++) {
18405 SharedLibraryInfo libraryInfo = versionedLib.valueAt(i);
18406 if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
18407 libraryInfo.getLongVersion()) < 0) {
18410 final long libVersionCode = libraryInfo.getDeclaringPackage().getLongVersionCode();
18411 if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
18412 if (libVersionCode == versionCode) {
18413 return libraryInfo.getPackageName();
18415 } else if (highestVersion == null) {
18416 highestVersion = libraryInfo;
18417 } else if (libVersionCode > highestVersion
18418 .getDeclaringPackage().getLongVersionCode()) {
18419 highestVersion = libraryInfo;
18423 if (highestVersion != null) {
18424 return highestVersion.getPackageName();
18427 return packageName;
18430 boolean isCallerVerifier(int callingUid) {
18431 final int callingUserId = UserHandle.getUserId(callingUid);
18432 return mRequiredVerifierPackage != null &&
18433 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
18436 private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
18437 if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
18438 || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
18441 final int callingUserId = UserHandle.getUserId(callingUid);
18442 // If the caller installed the pkgName, then allow it to silently uninstall.
18443 if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
18447 // Allow package verifier to silently uninstall.
18448 if (mRequiredVerifierPackage != null &&
18449 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
18453 // Allow package uninstaller to silently uninstall.
18454 if (mRequiredUninstallerPackage != null &&
18455 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
18459 // Allow storage manager to silently uninstall.
18460 if (mStorageManagerPackage != null &&
18461 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
18465 // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
18466 // uninstall for device owner provisioning.
18467 if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
18468 == PERMISSION_GRANTED) {
18475 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
18476 int[] result = EMPTY_INT_ARRAY;
18477 for (int userId : userIds) {
18478 if (getBlockUninstallForUser(packageName, userId)) {
18479 result = ArrayUtils.appendInt(result, userId);
18486 public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
18487 final int callingUid = Binder.getCallingUid();
18488 if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
18489 != PERMISSION_GRANTED) {
18490 EventLog.writeEvent(0x534e4554, "128599183", -1, "");
18491 throw new SecurityException(android.Manifest.permission.MANAGE_USERS
18492 + " permission is required to call this API");
18494 if (getInstantAppPackageName(callingUid) != null
18495 && !isCallerSameApp(packageName, callingUid)) {
18498 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
18501 private boolean isPackageDeviceAdmin(String packageName, int userId) {
18502 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
18503 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
18506 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
18507 /* callingUserOnly =*/ false);
18508 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
18509 : deviceOwnerComponentName.getPackageName();
18510 // Does the package contains the device owner?
18511 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise,
18512 // this check is probably not needed, since DO should be registered as a device
18513 // admin on some user too. (Original bug for this: b/17657954)
18514 if (packageName.equals(deviceOwnerPackageName)) {
18517 // Does it contain a device admin for any user?
18519 if (userId == UserHandle.USER_ALL) {
18520 users = sUserManager.getUserIds();
18522 users = new int[]{userId};
18524 for (int i = 0; i < users.length; ++i) {
18525 if (dpm.packageHasActiveAdmins(packageName, users[i])) {
18530 } catch (RemoteException e) {
18535 private boolean shouldKeepUninstalledPackageLPr(String packageName) {
18536 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
18540 * This method is an internal method that could be get invoked either
18541 * to delete an installed package or to clean up a failed installation.
18542 * After deleting an installed package, a broadcast is sent to notify any
18543 * listeners that the package has been removed. For cleaning up a failed
18544 * installation, the broadcast is not necessary since the package's
18545 * installation wouldn't have sent the initial broadcast either
18546 * The key steps in deleting a package are
18547 * deleting the package information in internal structures like mPackages,
18548 * deleting the packages base directories through installd
18549 * updating mSettings to reflect current status
18550 * persisting settings for later use
18551 * sending a broadcast if necessary
18553 int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
18554 final PackageRemovedInfo info = new PackageRemovedInfo(this);
18557 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
18558 ? UserHandle.USER_ALL : userId;
18560 if (isPackageDeviceAdmin(packageName, removeUser)) {
18561 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
18562 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
18565 final PackageSetting uninstalledPs;
18566 final PackageSetting disabledSystemPs;
18567 final PackageParser.Package pkg;
18569 // for the uninstall-updates case and restricted profiles, remember the per-
18570 // user handle installed state
18572 /** enabled state of the uninstalled application */
18573 final int origEnabledState;
18574 synchronized (mPackages) {
18575 uninstalledPs = mSettings.mPackages.get(packageName);
18576 if (uninstalledPs == null) {
18577 Slog.w(TAG, "Not removing non-existent package " + packageName);
18578 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18581 if (versionCode != PackageManager.VERSION_CODE_HIGHEST
18582 && uninstalledPs.versionCode != versionCode) {
18583 Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
18584 + uninstalledPs.versionCode + " != " + versionCode);
18585 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18588 disabledSystemPs = mSettings.getDisabledSystemPkgLPr(packageName);
18589 // Save the enabled state before we delete the package. When deleting a stub
18590 // application we always set the enabled state to 'disabled'.
18591 origEnabledState = uninstalledPs == null
18592 ? COMPONENT_ENABLED_STATE_DEFAULT : uninstalledPs.getEnabled(userId);
18593 // Static shared libs can be declared by any package, so let us not
18594 // allow removing a package if it provides a lib others depend on.
18595 pkg = mPackages.get(packageName);
18597 allUsers = sUserManager.getUserIds();
18599 if (pkg != null && pkg.staticSharedLibName != null) {
18600 SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(pkg.staticSharedLibName,
18601 pkg.staticSharedLibVersion);
18602 if (libraryInfo != null) {
18603 for (int currUserId : allUsers) {
18604 if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
18607 List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
18608 libraryInfo, MATCH_KNOWN_PACKAGES, currUserId);
18609 if (!ArrayUtils.isEmpty(libClientPackages)) {
18610 Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
18611 + " hosting lib " + libraryInfo.getName() + " version "
18612 + libraryInfo.getLongVersion() + " used by " + libClientPackages
18613 + " for user " + currUserId);
18614 return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
18620 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
18623 final int freezeUser;
18624 if (isUpdatedSystemApp(uninstalledPs)
18625 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
18626 // We're downgrading a system app, which will apply to all users, so
18627 // freeze them all during the downgrade
18628 freezeUser = UserHandle.USER_ALL;
18630 freezeUser = removeUser;
18633 synchronized (mInstallLock) {
18634 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
18635 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
18636 deleteFlags, "deletePackageX")) {
18637 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
18638 deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
18640 synchronized (mPackages) {
18643 mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
18645 updateSequenceNumberLP(uninstalledPs, info.removedUsers);
18646 updateInstantAppInstallerLocked(packageName);
18652 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
18653 info.sendPackageRemovedBroadcasts(killApp);
18654 info.sendSystemPackageUpdatedBroadcasts();
18655 info.sendSystemPackageAppearedBroadcasts();
18657 // Force a gc here.
18658 Runtime.getRuntime().gc();
18659 // Delete the resources here after sending the broadcast to let
18660 // other processes clean up before deleting resources.
18661 synchronized (mInstallLock) {
18662 if (info.args != null) {
18663 info.args.doPostDeleteLI(true);
18665 final PackageParser.Package stubPkg =
18666 (disabledSystemPs == null) ? null : disabledSystemPs.pkg;
18667 if (stubPkg != null && stubPkg.isStub) {
18668 synchronized (mPackages) {
18669 // restore the enabled state of the stub; the state is overwritten when
18670 // the stub is uninstalled
18671 final PackageSetting stubPs = mSettings.mPackages.get(stubPkg.packageName);
18672 if (stubPs != null) {
18673 stubPs.setEnabled(origEnabledState, userId, "android");
18676 if (origEnabledState == COMPONENT_ENABLED_STATE_DEFAULT
18677 || origEnabledState == COMPONENT_ENABLED_STATE_ENABLED) {
18678 if (DEBUG_COMPRESSION) {
18679 Slog.i(TAG, "Enabling system stub after removal; pkg: "
18680 + stubPkg.packageName);
18682 enableCompressedPackage(stubPkg);
18687 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18690 static class PackageRemovedInfo {
18691 final PackageSender packageSender;
18692 String removedPackage;
18693 String installerPackageName;
18695 int removedAppId = -1;
18697 int[] removedUsers = null;
18698 int[] broadcastUsers = null;
18699 int[] instantUserIds = null;
18700 SparseArray<Integer> installReasons;
18701 boolean isRemovedPackageSystemUpdate = false;
18703 boolean dataRemoved;
18704 boolean removedForAllUsers;
18705 boolean isStaticSharedLib;
18706 // Clean up resources deleted packages.
18707 InstallArgs args = null;
18708 ArrayMap<String, PackageRemovedInfo> removedChildPackages;
18709 ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
18711 PackageRemovedInfo(PackageSender packageSender) {
18712 this.packageSender = packageSender;
18715 void sendPackageRemovedBroadcasts(boolean killApp) {
18716 sendPackageRemovedBroadcastInternal(killApp);
18717 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
18718 for (int i = 0; i < childCount; i++) {
18719 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18720 childInfo.sendPackageRemovedBroadcastInternal(killApp);
18724 void sendSystemPackageUpdatedBroadcasts() {
18725 if (isRemovedPackageSystemUpdate) {
18726 sendSystemPackageUpdatedBroadcastsInternal();
18727 final int childCount = (removedChildPackages != null)
18728 ? removedChildPackages.size() : 0;
18729 for (int i = 0; i < childCount; i++) {
18730 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18731 if (childInfo.isRemovedPackageSystemUpdate) {
18732 childInfo.sendSystemPackageUpdatedBroadcastsInternal();
18738 void sendSystemPackageAppearedBroadcasts() {
18739 final int packageCount = (appearedChildPackages != null)
18740 ? appearedChildPackages.size() : 0;
18741 for (int i = 0; i < packageCount; i++) {
18742 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
18743 packageSender.sendPackageAddedForNewUsers(installedInfo.name,
18744 true /*sendBootCompleted*/, false /*startReceiver*/,
18745 UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers, null);
18749 private void sendSystemPackageUpdatedBroadcastsInternal() {
18750 Bundle extras = new Bundle(2);
18751 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
18752 extras.putBoolean(Intent.EXTRA_REPLACING, true);
18753 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18754 removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
18755 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18756 removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
18757 packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
18758 null, null, 0, removedPackage, null, null, null);
18759 if (installerPackageName != null) {
18760 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18761 removedPackage, extras, 0 /*flags*/,
18762 installerPackageName, null, null, null);
18763 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18764 removedPackage, extras, 0 /*flags*/,
18765 installerPackageName, null, null, null);
18769 private void sendPackageRemovedBroadcastInternal(boolean killApp) {
18770 // Don't send static shared library removal broadcasts as these
18771 // libs are visible only the the apps that depend on them an one
18772 // cannot remove the library if it has a dependency.
18773 if (isStaticSharedLib) {
18776 Bundle extras = new Bundle(2);
18777 final int removedUid = removedAppId >= 0 ? removedAppId : uid;
18778 extras.putInt(Intent.EXTRA_UID, removedUid);
18779 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
18780 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
18781 if (isUpdate || isRemovedPackageSystemUpdate) {
18782 extras.putBoolean(Intent.EXTRA_REPLACING, true);
18784 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
18785 if (removedPackage != null) {
18786 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18787 removedPackage, extras, 0, null /*targetPackage*/, null,
18788 broadcastUsers, instantUserIds);
18789 if (installerPackageName != null) {
18790 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18791 removedPackage, extras, 0 /*flags*/,
18792 installerPackageName, null, broadcastUsers, instantUserIds);
18794 if (dataRemoved && !isRemovedPackageSystemUpdate) {
18795 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
18796 removedPackage, extras,
18797 Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18798 null, null, broadcastUsers, instantUserIds);
18799 packageSender.notifyPackageRemoved(removedPackage, removedUid);
18802 if (removedAppId >= 0) {
18803 packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
18804 null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18805 null, null, broadcastUsers, instantUserIds);
18809 void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
18810 removedUsers = userIds;
18811 if (removedUsers == null) {
18812 broadcastUsers = null;
18816 broadcastUsers = EMPTY_INT_ARRAY;
18817 instantUserIds = EMPTY_INT_ARRAY;
18818 for (int i = userIds.length - 1; i >= 0; --i) {
18819 final int userId = userIds[i];
18820 if (deletedPackageSetting.getInstantApp(userId)) {
18821 instantUserIds = ArrayUtils.appendInt(instantUserIds, userId);
18823 broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
18830 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
18831 * flag is not set, the data directory is removed as well.
18832 * make sure this flag is set for partially installed apps. If not its meaningless to
18833 * delete a partially installed application.
18835 private void removePackageDataLIF(final PackageSetting deletedPs, int[] allUserHandles,
18836 PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
18837 String packageName = deletedPs.name;
18838 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + deletedPs);
18839 // Retrieve object to delete permissions for shared user later on
18840 final PackageParser.Package deletedPkg = deletedPs.pkg;
18841 if (outInfo != null) {
18842 outInfo.removedPackage = packageName;
18843 outInfo.installerPackageName = deletedPs.installerPackageName;
18844 outInfo.isStaticSharedLib = deletedPkg != null
18845 && deletedPkg.staticSharedLibName != null;
18846 outInfo.populateUsers(deletedPs == null ? null
18847 : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
18850 removePackageLI(deletedPs.name, (flags & PackageManager.DELETE_CHATTY) != 0);
18852 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
18853 final PackageParser.Package resolvedPkg;
18854 if (deletedPkg != null) {
18855 resolvedPkg = deletedPkg;
18857 // We don't have a parsed package when it lives on an ejected
18858 // adopted storage device, so fake something together
18859 resolvedPkg = new PackageParser.Package(deletedPs.name);
18860 resolvedPkg.setVolumeUuid(deletedPs.volumeUuid);
18862 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
18863 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
18864 destroyAppProfilesLIF(resolvedPkg);
18865 if (outInfo != null) {
18866 outInfo.dataRemoved = true;
18870 int removedAppId = -1;
18873 boolean installedStateChanged = false;
18874 if (deletedPs != null) {
18875 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
18876 final SparseBooleanArray changedUsers = new SparseBooleanArray();
18877 synchronized (mPackages) {
18878 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
18879 clearDefaultBrowserIfNeeded(packageName);
18880 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
18881 removedAppId = mSettings.removePackageLPw(packageName);
18882 if (outInfo != null) {
18883 outInfo.removedAppId = removedAppId;
18885 mPermissionManager.updatePermissions(
18886 deletedPs.name, null, false, mPackages.values(), mPermissionCallback);
18887 if (deletedPs.sharedUser != null) {
18888 // Remove permissions associated with package. Since runtime
18889 // permissions are per user we have to kill the removed package
18890 // or packages running under the shared user of the removed
18891 // package if revoking the permissions requested only by the removed
18892 // package is successful and this causes a change in gids.
18893 for (int userId : UserManagerService.getInstance().getUserIds()) {
18894 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
18896 if (userIdToKill == UserHandle.USER_ALL
18897 || userIdToKill >= UserHandle.USER_SYSTEM) {
18898 // If gids changed for this user, kill all affected packages.
18899 mHandler.post(() -> {
18900 // This has to happen with no lock held.
18901 killApplication(deletedPs.name, deletedPs.appId,
18902 KILL_APP_REASON_GIDS_CHANGED);
18908 clearPackagePreferredActivitiesLPw(
18909 deletedPs.name, changedUsers, UserHandle.USER_ALL);
18911 if (changedUsers.size() > 0) {
18912 updateDefaultHomeNotLocked(changedUsers);
18913 postPreferredActivityChangedBroadcast(UserHandle.USER_ALL);
18916 // make sure to preserve per-user disabled state if this removal was just
18917 // a downgrade of a system app to the factory package
18918 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18919 if (DEBUG_REMOVE) {
18920 Slog.d(TAG, "Propagating install state across downgrade");
18922 for (int userId : allUserHandles) {
18923 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18924 if (DEBUG_REMOVE) {
18925 Slog.d(TAG, " user " + userId + " => " + installed);
18927 if (installed != deletedPs.getInstalled(userId)) {
18928 installedStateChanged = true;
18930 deletedPs.setInstalled(installed, userId);
18934 synchronized (mPackages) {
18935 // can downgrade to reader
18936 if (writeSettings) {
18937 // Save settings now
18938 mSettings.writeLPr();
18940 if (installedStateChanged) {
18941 mSettings.writeKernelMappingLPr(deletedPs);
18944 if (removedAppId != -1) {
18945 // A user ID was deleted here. Go through all users and remove it
18947 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
18951 static boolean locationIsPrivileged(String path) {
18953 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
18954 final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
18955 final File privilegedOdmAppDir = new File(Environment.getOdmDirectory(), "priv-app");
18956 final File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
18957 final File privilegedProductServicesAppDir =
18958 new File(Environment.getProductServicesDirectory(), "priv-app");
18959 return path.startsWith(privilegedAppDir.getCanonicalPath() + "/")
18960 || path.startsWith(privilegedVendorAppDir.getCanonicalPath() + "/")
18961 || path.startsWith(privilegedOdmAppDir.getCanonicalPath() + "/")
18962 || path.startsWith(privilegedProductAppDir.getCanonicalPath() + "/")
18963 || path.startsWith(privilegedProductServicesAppDir.getCanonicalPath() + "/");
18964 } catch (IOException e) {
18965 Slog.e(TAG, "Unable to access code path " + path);
18970 static boolean locationIsOem(String path) {
18972 return path.startsWith(Environment.getOemDirectory().getCanonicalPath() + "/");
18973 } catch (IOException e) {
18974 Slog.e(TAG, "Unable to access code path " + path);
18979 static boolean locationIsVendor(String path) {
18981 return path.startsWith(Environment.getVendorDirectory().getCanonicalPath() + "/")
18982 || path.startsWith(Environment.getOdmDirectory().getCanonicalPath() + "/");
18983 } catch (IOException e) {
18984 Slog.e(TAG, "Unable to access code path " + path);
18989 static boolean locationIsProduct(String path) {
18991 return path.startsWith(Environment.getProductDirectory().getCanonicalPath() + "/");
18992 } catch (IOException e) {
18993 Slog.e(TAG, "Unable to access code path " + path);
18998 static boolean locationIsProductServices(String path) {
19000 return path.startsWith(
19001 Environment.getProductServicesDirectory().getCanonicalPath() + "/");
19002 } catch (IOException e) {
19003 Slog.e(TAG, "Unable to access code path " + path);
19008 static boolean locationIsOdm(String path) {
19010 return path.startsWith(Environment.getOdmDirectory().getCanonicalPath() + "/");
19011 } catch (IOException e) {
19012 Slog.e(TAG, "Unable to access code path " + path);
19018 * Tries to delete system package.
19020 private void deleteSystemPackageLIF(DeletePackageAction action, PackageSetting deletedPs,
19021 int[] allUserHandles, int flags, @Nullable PackageRemovedInfo outInfo,
19022 boolean writeSettings)
19023 throws SystemDeleteException {
19024 final boolean applyUserRestrictions =
19025 (allUserHandles != null) && outInfo != null && (outInfo.origUsers != null);
19026 final PackageParser.Package deletedPkg = deletedPs.pkg;
19027 // Confirm if the system package has been updated
19028 // An updated system app can be deleted. This will also have to restore
19029 // the system pkg from system partition
19031 final PackageSetting disabledPs = action.disabledPs;
19032 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
19033 + " disabledPs=" + disabledPs);
19034 Slog.d(TAG, "Deleting system pkg from data partition");
19036 if (DEBUG_REMOVE) {
19037 if (applyUserRestrictions) {
19038 Slog.d(TAG, "Remembering install states:");
19039 for (int userId : allUserHandles) {
19040 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
19041 Slog.d(TAG, " u=" + userId + " inst=" + finstalled);
19046 if (outInfo != null) {
19047 // Delete the updated package
19048 outInfo.isRemovedPackageSystemUpdate = true;
19049 if (outInfo.removedChildPackages != null) {
19050 final int childCount = (deletedPs.childPackageNames != null)
19051 ? deletedPs.childPackageNames.size() : 0;
19052 for (int i = 0; i < childCount; i++) {
19053 String childPackageName = deletedPs.childPackageNames.get(i);
19054 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
19055 .contains(childPackageName)) {
19056 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
19058 if (childInfo != null) {
19059 childInfo.isRemovedPackageSystemUpdate = true;
19066 if (disabledPs.versionCode < deletedPs.versionCode) {
19067 // Delete data for downgrades
19068 flags &= ~PackageManager.DELETE_KEEP_DATA;
19070 // Preserve data by setting flag
19071 flags |= PackageManager.DELETE_KEEP_DATA;
19074 deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
19075 outInfo, writeSettings, disabledPs.pkg);
19078 synchronized (mPackages) {
19079 // NOTE: The system package always needs to be enabled; even if it's for
19080 // a compressed stub. If we don't, installing the system package fails
19081 // during scan [scanning checks the disabled packages]. We will reverse
19082 // this later, after we've "installed" the stub.
19083 // Reinstate the old system package
19084 enableSystemPackageLPw(disabledPs.pkg);
19085 // Remove any native libraries from the upgraded package.
19086 removeNativeBinariesLI(deletedPs);
19089 // Install the system package
19090 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
19092 installPackageFromSystemLIF(disabledPs.codePathString, allUserHandles,
19093 outInfo == null ? null : outInfo.origUsers, deletedPs.getPermissionsState(),
19095 } catch (PackageManagerException e) {
19096 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
19098 // TODO(patb): can we avoid this; throw would come from scan...
19099 throw new SystemDeleteException(e);
19101 if (disabledPs.pkg.isStub) {
19102 // We've re-installed the stub; make sure it's disabled here. If package was
19103 // originally enabled, we'll install the compressed version of the application
19104 // and re-enable it afterward.
19105 final PackageSetting stubPs = mSettings.mPackages.get(deletedPkg.packageName);
19106 if (stubPs != null) {
19108 COMPONENT_ENABLED_STATE_DISABLED, UserHandle.USER_SYSTEM, "android");
19115 * Installs a package that's already on the system partition.
19117 private PackageParser.Package installPackageFromSystemLIF(@NonNull String codePathString,
19118 @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
19119 @Nullable PermissionsState origPermissionState, boolean writeSettings)
19120 throws PackageManagerException {
19121 @ParseFlags int parseFlags =
19123 | PackageParser.PARSE_MUST_BE_APK
19124 | PackageParser.PARSE_IS_SYSTEM_DIR;
19125 @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
19126 if (locationIsPrivileged(codePathString)) {
19127 scanFlags |= SCAN_AS_PRIVILEGED;
19129 if (locationIsOem(codePathString)) {
19130 scanFlags |= SCAN_AS_OEM;
19132 if (locationIsVendor(codePathString)) {
19133 scanFlags |= SCAN_AS_VENDOR;
19135 if (locationIsProduct(codePathString)) {
19136 scanFlags |= SCAN_AS_PRODUCT;
19138 if (locationIsProductServices(codePathString)) {
19139 scanFlags |= SCAN_AS_PRODUCT_SERVICES;
19141 if (locationIsOdm(codePathString)) {
19142 scanFlags |= SCAN_AS_ODM;
19145 final File codePath = new File(codePathString);
19146 final PackageParser.Package pkg =
19147 scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
19150 // update shared libraries for the newly re-installed system package
19151 updateSharedLibrariesLocked(pkg, null, Collections.unmodifiableMap(mPackages));
19152 } catch (PackageManagerException e) {
19153 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
19156 prepareAppDataAfterInstallLIF(pkg);
19159 synchronized (mPackages) {
19160 PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
19162 // Propagate the permissions state as we do not want to drop on the floor
19163 // runtime permissions. The update permissions method below will take
19164 // care of removing obsolete permissions and grant install permissions.
19165 if (origPermissionState != null) {
19166 ps.getPermissionsState().copyFrom(origPermissionState);
19168 mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
19169 mPermissionCallback);
19171 final boolean applyUserRestrictions
19172 = (allUserHandles != null) && (origUserHandles != null);
19173 if (applyUserRestrictions) {
19174 boolean installedStateChanged = false;
19175 if (DEBUG_REMOVE) {
19176 Slog.d(TAG, "Propagating install state across reinstall");
19178 for (int userId : allUserHandles) {
19179 final boolean installed = ArrayUtils.contains(origUserHandles, userId);
19180 if (DEBUG_REMOVE) {
19181 Slog.d(TAG, " user " + userId + " => " + installed);
19183 if (installed != ps.getInstalled(userId)) {
19184 installedStateChanged = true;
19186 ps.setInstalled(installed, userId);
19188 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19190 // Regardless of writeSettings we need to ensure that this restriction
19191 // state propagation is persisted
19192 mSettings.writeAllUsersPackageRestrictionsLPr();
19193 if (installedStateChanged) {
19194 mSettings.writeKernelMappingLPr(ps);
19197 // can downgrade to reader here
19198 if (writeSettings) {
19199 mSettings.writeLPr();
19205 private void deleteInstalledPackageLIF(PackageSetting ps,
19206 boolean deleteCodeAndResources, int flags, int[] allUserHandles,
19207 PackageRemovedInfo outInfo, boolean writeSettings,
19208 PackageParser.Package replacingPackage) {
19209 synchronized (mPackages) {
19210 if (outInfo != null) {
19211 outInfo.uid = ps.appId;
19214 if (outInfo != null && outInfo.removedChildPackages != null) {
19215 final int childCount = (ps.childPackageNames != null)
19216 ? ps.childPackageNames.size() : 0;
19217 for (int i = 0; i < childCount; i++) {
19218 String childPackageName = ps.childPackageNames.get(i);
19219 PackageSetting childPs = mSettings.mPackages.get(childPackageName);
19220 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
19222 if (childInfo != null) {
19223 childInfo.uid = childPs.appId;
19229 // Delete package data from internal structures and also remove data if flag is set
19230 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
19232 // Delete the child packages data
19233 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
19234 for (int i = 0; i < childCount; i++) {
19235 PackageSetting childPs;
19236 synchronized (mPackages) {
19237 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
19239 if (childPs != null) {
19240 PackageRemovedInfo childOutInfo = (outInfo != null
19241 && outInfo.removedChildPackages != null)
19242 ? outInfo.removedChildPackages.get(childPs.name) : null;
19243 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
19244 && (replacingPackage != null
19245 && !replacingPackage.hasChildPackage(childPs.name))
19246 ? flags & ~DELETE_KEEP_DATA : flags;
19247 removePackageDataLIF(childPs, allUserHandles, childOutInfo,
19248 deleteFlags, writeSettings);
19252 // Delete application code and resources only for parent packages
19253 if (ps.parentPackageName == null) {
19254 if (deleteCodeAndResources && (outInfo != null)) {
19255 outInfo.args = createInstallArgsForExisting(
19256 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
19257 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
19263 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
19265 mContext.enforceCallingOrSelfPermission(
19266 android.Manifest.permission.DELETE_PACKAGES, null);
19267 synchronized (mPackages) {
19268 // Cannot block uninstall of static shared libs as they are
19269 // considered a part of the using app (emulating static linking).
19270 // Also static libs are installed always on internal storage.
19271 PackageParser.Package pkg = mPackages.get(packageName);
19272 if (pkg != null && pkg.staticSharedLibName != null) {
19273 Slog.w(TAG, "Cannot block uninstall of package: " + packageName
19274 + " providing static shared library: " + pkg.staticSharedLibName);
19277 mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
19278 mSettings.writePackageRestrictionsLPr(userId);
19284 public boolean getBlockUninstallForUser(String packageName, int userId) {
19285 synchronized (mPackages) {
19286 final PackageSetting ps = mSettings.mPackages.get(packageName);
19287 if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
19290 return mSettings.getBlockUninstallLPr(userId, packageName);
19295 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
19296 enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
19297 synchronized (mPackages) {
19298 PackageSetting ps = mSettings.mPackages.get(packageName);
19300 Log.w(TAG, "Package doesn't exist: " + packageName);
19303 if (systemUserApp) {
19304 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
19306 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
19308 mSettings.writeLPr();
19313 private static class DeletePackageAction {
19314 public final PackageSetting deletingPs;
19315 public final PackageSetting disabledPs;
19316 public final PackageRemovedInfo outInfo;
19317 public final int flags;
19318 public final UserHandle user;
19320 private DeletePackageAction(PackageSetting deletingPs, PackageSetting disabledPs,
19321 PackageRemovedInfo outInfo, int flags, UserHandle user) {
19322 this.deletingPs = deletingPs;
19323 this.disabledPs = disabledPs;
19324 this.outInfo = outInfo;
19325 this.flags = flags;
19331 * @return a {@link DeletePackageAction} if the provided package and related state may be
19332 * deleted, {@code null} otherwise.
19335 @GuardedBy("mPackages")
19336 private static DeletePackageAction mayDeletePackageLocked(
19337 PackageRemovedInfo outInfo, PackageSetting ps, @Nullable PackageSetting disabledPs,
19338 @Nullable PackageSetting[] children, int flags, UserHandle user) {
19342 if (isSystemApp(ps)) {
19343 if (ps.parentPackageName != null) {
19344 Slog.w(TAG, "Attempt to delete child system package " + ps.pkg.packageName);
19348 final boolean deleteSystem = (flags & PackageManager.DELETE_SYSTEM_APP) != 0;
19349 final boolean deleteAllUsers =
19350 user == null || user.getIdentifier() == UserHandle.USER_ALL;
19351 if ((!deleteSystem || deleteAllUsers) && disabledPs == null) {
19352 Slog.w(TAG, "Attempt to delete unknown system package " + ps.pkg.packageName);
19355 // Confirmed if the system package has been updated
19356 // An updated system app can be deleted. This will also have to restore
19357 // the system pkg from system partition reader
19359 final int parentReferenceCount =
19360 (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
19361 final int childCount = children != null ? children.length : 0;
19362 if (childCount != parentReferenceCount) {
19365 if (childCount != 0 && outInfo != null && outInfo.removedChildPackages != null) {
19366 for (PackageSetting child : children) {
19367 if (child == null || !ps.childPackageNames.contains(child.name)) {
19372 return new DeletePackageAction(ps, disabledPs, outInfo, flags, user);
19376 * This method handles package deletion in general
19378 private boolean deletePackageLIF(@NonNull String packageName, UserHandle user,
19379 boolean deleteCodeAndResources, int[] allUserHandles, int flags,
19380 PackageRemovedInfo outInfo, boolean writeSettings,
19381 PackageParser.Package replacingPackage) {
19382 final DeletePackageAction action;
19383 synchronized (mPackages) {
19384 final PackageSetting ps = mSettings.mPackages.get(packageName);
19385 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
19386 PackageSetting[] children = mSettings.getChildSettingsLPr(ps);
19387 action = mayDeletePackageLocked(outInfo, ps, disabledPs, children, flags, user);
19389 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
19390 if (null == action) {
19391 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: action was null");
19397 executeDeletePackageLIF(action, packageName, deleteCodeAndResources,
19398 allUserHandles, writeSettings, replacingPackage);
19399 } catch (SystemDeleteException e) {
19400 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: system deletion failure", e);
19406 private static class SystemDeleteException extends Exception {
19407 public final PackageManagerException reason;
19409 private SystemDeleteException(PackageManagerException reason) {
19410 this.reason = reason;
19414 /** Deletes a package. Only throws when install of a disabled package fails. */
19415 private void executeDeletePackageLIF(DeletePackageAction action,
19416 String packageName, boolean deleteCodeAndResources,
19417 int[] allUserHandles, boolean writeSettings,
19418 PackageParser.Package replacingPackage) throws SystemDeleteException {
19419 final PackageSetting ps = action.deletingPs;
19420 final PackageRemovedInfo outInfo = action.outInfo;
19421 final UserHandle user = action.user;
19422 final int flags = action.flags;
19423 final boolean systemApp = isSystemApp(ps);
19425 if (ps.parentPackageName != null
19426 && (!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
19427 if (DEBUG_REMOVE) {
19428 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
19429 + ((user == null) ? UserHandle.USER_ALL : user));
19431 final int removedUserId = (user != null) ? user.getIdentifier()
19432 : UserHandle.USER_ALL;
19434 clearPackageStateForUserLIF(ps, removedUserId, outInfo, flags);
19435 synchronized (mPackages) {
19436 markPackageUninstalledForUserLPw(ps, user);
19437 scheduleWritePackageRestrictionsLocked(user);
19442 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
19443 if (ps.getPermissionsState().hasPermission(Manifest.permission.SUSPEND_APPS, userId)) {
19444 unsuspendForSuspendingPackage(packageName, userId);
19446 if ((!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)
19447 && userId != UserHandle.USER_ALL) {
19448 // The caller is asking that the package only be deleted for a single
19449 // user. To do this, we just mark its uninstalled state and delete
19450 // its data. If this is a system app, we only allow this to happen if
19451 // they have set the special DELETE_SYSTEM_APP which requests different
19452 // semantics than normal for uninstalling system apps.
19453 final boolean clearPackageStateAndReturn;
19454 synchronized (mPackages) {
19455 markPackageUninstalledForUserLPw(ps, user);
19457 // Do not uninstall the APK if an app should be cached
19458 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
19459 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
19460 // Other users still have this package installed, so all
19461 // we need to do is clear this user's data and save that
19462 // it is uninstalled.
19463 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
19464 clearPackageStateAndReturn = true;
19466 // We need to set it back to 'installed' so the uninstall
19467 // broadcasts will be sent correctly.
19468 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
19469 ps.setInstalled(true, userId);
19470 mSettings.writeKernelMappingLPr(ps);
19471 clearPackageStateAndReturn = false;
19474 // This is a system app, so we assume that the
19475 // other users still have this package installed, so all
19476 // we need to do is clear this user's data and save that
19477 // it is uninstalled.
19478 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
19479 clearPackageStateAndReturn = true;
19482 if (clearPackageStateAndReturn) {
19483 clearPackageStateForUserLIF(ps, userId, outInfo, flags);
19484 synchronized (mPackages) {
19485 scheduleWritePackageRestrictionsLocked(user);
19491 // If we are deleting a composite package for all users, keep track
19492 // of result for each child.
19493 if (ps.childPackageNames != null && outInfo != null) {
19494 synchronized (mPackages) {
19495 final int childCount = ps.childPackageNames.size();
19496 outInfo.removedChildPackages = new ArrayMap<>(childCount);
19497 for (int i = 0; i < childCount; i++) {
19498 String childPackageName = ps.childPackageNames.get(i);
19499 PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
19500 childInfo.removedPackage = childPackageName;
19501 childInfo.installerPackageName = ps.installerPackageName;
19502 outInfo.removedChildPackages.put(childPackageName, childInfo);
19503 PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
19504 if (childPs != null) {
19505 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
19511 // TODO(b/109941548): break reasons for ret = false out into mayDelete method
19513 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
19514 // When an updated system application is deleted we delete the existing resources
19515 // as well and fall back to existing code in system partition
19516 deleteSystemPackageLIF(action, ps, allUserHandles, flags, outInfo, writeSettings);
19518 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
19519 deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
19520 outInfo, writeSettings, replacingPackage);
19523 // Take a note whether we deleted the package for all users
19524 if (outInfo != null) {
19525 outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
19526 if (outInfo.removedChildPackages != null) {
19527 synchronized (mPackages) {
19528 final int childCount = outInfo.removedChildPackages.size();
19529 for (int i = 0; i < childCount; i++) {
19530 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
19531 if (childInfo != null) {
19532 childInfo.removedForAllUsers = mPackages.get(
19533 childInfo.removedPackage) == null;
19538 // If we uninstalled an update to a system app there may be some
19539 // child packages that appeared as they are declared in the system
19540 // app but were not declared in the update.
19542 synchronized (mPackages) {
19543 PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
19544 final int childCount = (updatedPs.childPackageNames != null)
19545 ? updatedPs.childPackageNames.size() : 0;
19546 for (int i = 0; i < childCount; i++) {
19547 String childPackageName = updatedPs.childPackageNames.get(i);
19548 if (outInfo.removedChildPackages == null
19549 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
19550 PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
19551 if (childPs == null) {
19554 PackageInstalledInfo installRes = new PackageInstalledInfo();
19555 installRes.name = childPackageName;
19556 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
19557 installRes.pkg = mPackages.get(childPackageName);
19558 installRes.uid = childPs.pkg.applicationInfo.uid;
19559 if (outInfo.appearedChildPackages == null) {
19560 outInfo.appearedChildPackages = new ArrayMap<>();
19562 outInfo.appearedChildPackages.put(childPackageName, installRes);
19570 @GuardedBy("mPackages")
19571 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
19572 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
19573 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
19574 for (int nextUserId : userIds) {
19575 if (DEBUG_REMOVE) {
19576 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
19578 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
19579 false /*installed*/,
19581 true /*notLaunched*/,
19583 0 /*distractionFlags*/,
19584 false /*suspended*/,
19585 null /*suspendingPackage*/,
19586 null /*dialogInfo*/,
19587 null /*suspendedAppExtras*/,
19588 null /*suspendedLauncherExtras*/,
19589 false /*instantApp*/,
19590 false /*virtualPreload*/,
19591 null /*lastDisableAppCaller*/,
19592 null /*enabledComponents*/,
19593 null /*disabledComponents*/,
19594 ps.readUserState(nextUserId).domainVerificationStatus,
19595 0, PackageManager.INSTALL_REASON_UNKNOWN,
19596 null /*harmfulAppWarning*/);
19598 mSettings.writeKernelMappingLPr(ps);
19601 private void clearPackageStateForUserLIF(PackageSetting ps, int userId,
19602 PackageRemovedInfo outInfo, int flags) {
19603 final PackageParser.Package pkg;
19604 synchronized (mPackages) {
19605 pkg = mPackages.get(ps.name);
19608 destroyAppProfilesLIF(pkg);
19610 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
19611 : new int[] {userId};
19612 for (int nextUserId : userIds) {
19613 if (DEBUG_REMOVE) {
19614 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
19618 destroyAppDataLIF(pkg, nextUserId,
19619 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
19620 clearDefaultBrowserIfNeededForUser(ps.name, nextUserId);
19621 removeKeystoreDataIfNeeded(nextUserId, ps.appId);
19622 final SparseBooleanArray changedUsers = new SparseBooleanArray();
19623 clearPackagePreferredActivitiesLPw(ps.name, changedUsers, nextUserId);
19624 if (changedUsers.size() > 0) {
19625 updateDefaultHomeNotLocked(changedUsers);
19626 postPreferredActivityChangedBroadcast(nextUserId);
19627 synchronized (mPackages) {
19628 scheduleWritePackageRestrictionsLocked(nextUserId);
19631 synchronized (mPackages) {
19632 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
19634 // Also delete contributed media, when requested
19635 if ((flags & PackageManager.DELETE_CONTRIBUTED_MEDIA) != 0) {
19637 MediaStore.deleteContributedMedia(mContext, ps.name, UserHandle.of(nextUserId));
19638 } catch (IOException e) {
19639 Slog.w(TAG, "Failed to delete contributed media for " + ps.name, e);
19644 if (outInfo != null) {
19645 outInfo.removedPackage = ps.name;
19646 outInfo.installerPackageName = ps.installerPackageName;
19647 outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
19648 outInfo.removedAppId = ps.appId;
19649 outInfo.removedUsers = userIds;
19650 outInfo.broadcastUsers = userIds;
19655 public void clearApplicationProfileData(String packageName) {
19656 enforceSystemOrRoot("Only the system can clear all profile data");
19658 final PackageParser.Package pkg;
19659 synchronized (mPackages) {
19660 pkg = mPackages.get(packageName);
19663 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
19664 synchronized (mInstallLock) {
19665 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
19671 public void clearApplicationUserData(final String packageName,
19672 final IPackageDataObserver observer, final int userId) {
19673 mContext.enforceCallingOrSelfPermission(
19674 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
19676 final int callingUid = Binder.getCallingUid();
19677 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19678 true /* requireFullPermission */, false /* checkShell */, "clear application data");
19680 final PackageSetting ps = mSettings.getPackageLPr(packageName);
19681 final boolean filterApp = (ps != null && filterAppAccessLPr(ps, callingUid, userId));
19682 if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
19683 throw new SecurityException("Cannot clear data for a protected package: "
19686 // Queue up an async operation since the package deletion may take a little while.
19687 mHandler.post(new Runnable() {
19688 public void run() {
19689 mHandler.removeCallbacks(this);
19690 final boolean succeeded;
19692 try (PackageFreezer freezer = freezePackage(packageName,
19693 "clearApplicationUserData")) {
19694 synchronized (mInstallLock) {
19695 succeeded = clearApplicationUserDataLIF(packageName, userId);
19697 synchronized (mPackages) {
19698 mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
19699 packageName, userId);
19703 // invoke DeviceStorageMonitor's update method to clear any notifications
19704 DeviceStorageMonitorInternal dsm = LocalServices
19705 .getService(DeviceStorageMonitorInternal.class);
19709 if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
19710 == PERMISSION_GRANTED) {
19711 unsuspendForSuspendingPackage(packageName, userId);
19717 if (observer != null) {
19719 observer.onRemoveCompleted(packageName, succeeded);
19720 } catch (RemoteException e) {
19721 Log.i(TAG, "Observer no longer exists.");
19723 } //end if observer
19728 private boolean clearApplicationUserDataLIF(String packageName, int userId) {
19729 if (packageName == null) {
19730 Slog.w(TAG, "Attempt to delete null packageName.");
19734 // Try finding details about the requested package
19735 PackageParser.Package pkg;
19736 synchronized (mPackages) {
19737 pkg = mPackages.get(packageName);
19739 final PackageSetting ps = mSettings.mPackages.get(packageName);
19746 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
19750 PackageSetting ps = (PackageSetting) pkg.mExtras;
19751 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19754 clearAppDataLIF(pkg, userId,
19755 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
19757 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
19758 removeKeystoreDataIfNeeded(userId, appId);
19760 UserManagerInternal umInternal = getUserManagerInternal();
19762 if (umInternal.isUserUnlockingOrUnlocked(userId)) {
19763 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
19764 } else if (umInternal.isUserRunning(userId)) {
19765 flags = StorageManager.FLAG_STORAGE_DE;
19769 prepareAppDataContentsLIF(pkg, userId, flags);
19775 * Reverts user permission state changes (permissions and flags) in
19776 * all packages for a given user.
19778 * @param userId The device user for which to do a reset.
19780 @GuardedBy("mPackages")
19781 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
19782 final int packageCount = mPackages.size();
19783 for (int i = 0; i < packageCount; i++) {
19784 PackageParser.Package pkg = mPackages.valueAt(i);
19785 PackageSetting ps = (PackageSetting) pkg.mExtras;
19786 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19790 private void resetNetworkPolicies(int userId) {
19791 LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
19795 * Reverts user permission state changes (permissions and flags).
19797 * @param ps The package for which to reset.
19798 * @param userId The device user for which to do a reset.
19800 @GuardedBy("mPackages")
19801 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
19802 final PackageSetting ps, final int userId) {
19803 if (ps.pkg == null) {
19807 final String packageName = ps.pkg.packageName;
19809 // These are flags that can change base on user actions.
19810 final int userSettableMask = FLAG_PERMISSION_USER_SET
19811 | FLAG_PERMISSION_USER_FIXED
19812 | FLAG_PERMISSION_REVOKE_ON_UPGRADE
19813 | FLAG_PERMISSION_REVIEW_REQUIRED;
19815 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
19816 | FLAG_PERMISSION_POLICY_FIXED;
19818 // Delay and combine non-async permission callbacks
19819 final boolean[] permissionRemoved = new boolean[1];
19820 final ArraySet<Long> revokedPermissions = new ArraySet<>();
19821 final SparseBooleanArray updatedUsers = new SparseBooleanArray();
19823 PermissionCallback delayingPermCallback = new PermissionCallback() {
19824 public void onGidsChanged(int appId, int userId) {
19825 mPermissionCallback.onGidsChanged(appId, userId);
19828 public void onPermissionChanged() {
19829 mPermissionCallback.onPermissionChanged();
19832 public void onPermissionGranted(int uid, int userId) {
19833 mPermissionCallback.onPermissionGranted(uid, userId);
19836 public void onInstallPermissionGranted() {
19837 mPermissionCallback.onInstallPermissionGranted();
19840 public void onPermissionRevoked(int uid, int userId) {
19841 revokedPermissions.add(IntPair.of(uid, userId));
19843 updatedUsers.put(userId, true);
19846 public void onInstallPermissionRevoked() {
19847 mPermissionCallback.onInstallPermissionRevoked();
19850 public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
19851 for (int userId : updatedUserIds) {
19853 updatedUsers.put(userId, true);
19855 // Don't override sync=true by sync=false
19856 if (!updatedUsers.get(userId)) {
19857 updatedUsers.put(userId, false);
19863 public void onPermissionRemoved() {
19864 permissionRemoved[0] = true;
19867 public void onInstallPermissionUpdated() {
19868 mPermissionCallback.onInstallPermissionUpdated();
19872 final AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
19873 final int uid = UserHandle.getUid(userId, ps.pkg.applicationInfo.uid);
19875 final int permissionCount = ps.pkg.requestedPermissions.size();
19876 for (int i = 0; i < permissionCount; i++) {
19877 final String permName = ps.pkg.requestedPermissions.get(i);
19878 final BasePermission bp =
19879 (BasePermission) mPermissionManager.getPermissionTEMP(permName);
19884 if (bp.isRemoved()) {
19888 // If shared user we just reset the state to which only this app contributed.
19889 if (ps.sharedUser != null) {
19890 boolean used = false;
19891 final int packageCount = ps.sharedUser.packages.size();
19892 for (int j = 0; j < packageCount; j++) {
19893 PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
19894 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
19895 && pkg.pkg.requestedPermissions.contains(permName)) {
19905 final int oldFlags = mPermissionManager.getPermissionFlags(permName, packageName,
19906 Process.SYSTEM_UID, userId);
19908 // Always clear the user settable flags.
19909 // If permission review is enabled and this is a legacy app, mark the
19910 // permission as requiring a review as this is the initial state.
19912 if (ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M && bp.isRuntime()) {
19913 flags |= FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
19916 mPermissionManager.updatePermissionFlags(permName, packageName,
19917 userSettableMask, flags, Process.SYSTEM_UID, userId, false,
19918 delayingPermCallback);
19920 // Below is only runtime permission handling.
19921 if (!bp.isRuntime()) {
19925 // Never clobber system or policy.
19926 if ((oldFlags & policyOrSystemFlags) != 0) {
19930 // If this permission was granted by default, make sure it is.
19931 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
19932 mPermissionManager.grantRuntimePermission(permName, packageName, false,
19933 Process.SYSTEM_UID, userId, delayingPermCallback);
19934 // Allow app op later as we are holding mPackages
19935 // PermissionPolicyService will handle the app op for foreground/background
19937 String appOp = AppOpsManager.permissionToOp(permName);
19938 if (appOp != null) {
19939 mHandler.post(() -> appOpsManager.setUidMode(appOp, uid,
19940 AppOpsManager.MODE_ALLOWED));
19942 // If permission review is enabled the permissions for a legacy apps
19943 // are represented as constantly granted runtime ones, so don't revoke.
19944 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
19945 // Otherwise, reset the permission.
19946 mPermissionManager.revokeRuntimePermission(permName, packageName, false, userId,
19947 delayingPermCallback);
19951 // Execute delayed callbacks
19952 if (permissionRemoved[0]) {
19953 mPermissionCallback.onPermissionRemoved();
19956 // Slight variation on the code in mPermissionCallback.onPermissionRevoked() as we cannot
19957 // kill uid while holding mPackages-lock
19958 if (!revokedPermissions.isEmpty()) {
19959 int numRevokedPermissions = revokedPermissions.size();
19960 for (int i = 0; i < numRevokedPermissions; i++) {
19961 int revocationUID = IntPair.first(revokedPermissions.valueAt(i));
19962 int revocationUserId = IntPair.second(revokedPermissions.valueAt(i));
19964 mOnPermissionChangeListeners.onPermissionsChanged(revocationUID);
19966 // Kill app later as we are holding mPackages
19967 mHandler.post(() -> killUid(UserHandle.getAppId(revocationUID), revocationUserId,
19968 KILL_APP_REASON_PERMISSIONS_REVOKED));
19972 int numUpdatedUsers = updatedUsers.size();
19973 for (int i = 0; i < numUpdatedUsers; i++) {
19974 mSettings.writeRuntimePermissionsForUserLPr(updatedUsers.keyAt(i),
19975 updatedUsers.valueAt(i));
19980 * Remove entries from the keystore daemon. Will only remove it if the
19981 * {@code appId} is valid.
19983 private static void removeKeystoreDataIfNeeded(int userId, int appId) {
19988 final KeyStore keyStore = KeyStore.getInstance();
19989 if (keyStore != null) {
19990 if (userId == UserHandle.USER_ALL) {
19991 for (final int individual : sUserManager.getUserIds()) {
19992 keyStore.clearUid(UserHandle.getUid(individual, appId));
19995 keyStore.clearUid(UserHandle.getUid(userId, appId));
19998 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
20003 public void deleteApplicationCacheFiles(final String packageName,
20004 final IPackageDataObserver observer) {
20005 final int userId = UserHandle.getCallingUserId();
20006 deleteApplicationCacheFilesAsUser(packageName, userId, observer);
20010 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
20011 final IPackageDataObserver observer) {
20012 final int callingUid = Binder.getCallingUid();
20013 if (mContext.checkCallingOrSelfPermission(
20014 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES)
20015 != PackageManager.PERMISSION_GRANTED) {
20016 // If the caller has the old delete cache permission, silently ignore. Else throw.
20017 if (mContext.checkCallingOrSelfPermission(
20018 android.Manifest.permission.DELETE_CACHE_FILES)
20019 == PackageManager.PERMISSION_GRANTED) {
20020 Slog.w(TAG, "Calling uid " + callingUid + " does not have " +
20021 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES +
20022 ", silently ignoring");
20025 mContext.enforceCallingOrSelfPermission(
20026 android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
20028 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20029 /* requireFullPermission= */ true, /* checkShell= */ false,
20030 "delete application cache files");
20031 final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
20032 android.Manifest.permission.ACCESS_INSTANT_APPS);
20034 final PackageParser.Package pkg;
20035 synchronized (mPackages) {
20036 pkg = mPackages.get(packageName);
20039 // Queue up an async operation since the package deletion may take a little while.
20040 mHandler.post(() -> {
20041 final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
20042 boolean doClearData = true;
20044 final boolean targetIsInstantApp =
20045 ps.getInstantApp(UserHandle.getUserId(callingUid));
20046 doClearData = !targetIsInstantApp
20047 || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
20050 synchronized (mInstallLock) {
20051 final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL;
20052 // We're only clearing cache files, so we don't care if the
20053 // app is unfrozen and still able to run
20054 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
20055 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20058 if (observer != null) {
20060 observer.onRemoveCompleted(packageName, true);
20061 } catch (RemoteException e) {
20062 Log.i(TAG, "Observer no longer exists.");
20069 public void getPackageSizeInfo(final String packageName, int userHandle,
20070 final IPackageStatsObserver observer) {
20071 throw new UnsupportedOperationException(
20072 "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
20075 @GuardedBy("mInstallLock")
20076 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
20077 final PackageSetting ps;
20078 synchronized (mPackages) {
20079 ps = mSettings.mPackages.get(packageName);
20081 Slog.w(TAG, "Failed to find settings for " + packageName);
20086 final String[] packageNames = { packageName };
20087 final long[] ceDataInodes = { ps.getCeDataInode(userId) };
20088 final String[] codePaths = { ps.codePathString };
20091 mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
20092 ps.appId, ceDataInodes, codePaths, stats);
20094 // For now, ignore code size of packages on system partition
20095 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
20096 stats.codeSize = 0;
20099 // External clients expect these to be tracked separately
20100 stats.dataSize -= stats.cacheSize;
20102 } catch (InstallerException e) {
20103 Slog.w(TAG, String.valueOf(e));
20110 @GuardedBy("mPackages")
20111 private int getUidTargetSdkVersionLockedLPr(int uid) {
20112 final int appId = UserHandle.getAppId(uid);
20113 final Object obj = mSettings.getSettingLPr(appId);
20114 if (obj instanceof SharedUserSetting) {
20115 final SharedUserSetting sus = (SharedUserSetting) obj;
20116 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
20117 final Iterator<PackageSetting> it = sus.packages.iterator();
20118 while (it.hasNext()) {
20119 final PackageSetting ps = it.next();
20120 if (ps.pkg != null) {
20121 int v = ps.pkg.applicationInfo.targetSdkVersion;
20122 if (v < vers) vers = v;
20126 } else if (obj instanceof PackageSetting) {
20127 final PackageSetting ps = (PackageSetting) obj;
20128 if (ps.pkg != null) {
20129 return ps.pkg.applicationInfo.targetSdkVersion;
20132 return Build.VERSION_CODES.CUR_DEVELOPMENT;
20135 @GuardedBy("mPackages")
20136 private int getPackageTargetSdkVersionLockedLPr(String packageName) {
20137 final PackageParser.Package p = mPackages.get(packageName);
20139 return p.applicationInfo.targetSdkVersion;
20141 return Build.VERSION_CODES.CUR_DEVELOPMENT;
20145 public void addPreferredActivity(IntentFilter filter, int match,
20146 ComponentName[] set, ComponentName activity, int userId) {
20147 addPreferredActivityInternal(filter, match, set, activity, true, userId,
20148 "Adding preferred");
20151 private void addPreferredActivityInternal(IntentFilter filter, int match,
20152 ComponentName[] set, ComponentName activity, boolean always, int userId,
20155 int callingUid = Binder.getCallingUid();
20156 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20157 true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
20158 if (mContext.checkCallingOrSelfPermission(
20159 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20160 != PackageManager.PERMISSION_GRANTED) {
20161 if (getUidTargetSdkVersionLockedLPr(callingUid)
20162 < Build.VERSION_CODES.FROYO) {
20163 Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
20167 mContext.enforceCallingOrSelfPermission(
20168 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20170 if (filter.countActions() == 0) {
20171 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
20174 if (DEBUG_PREFERRED) {
20175 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
20177 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
20179 synchronized (mPackages) {
20180 final PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
20181 pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
20182 scheduleWritePackageRestrictionsLocked(userId);
20184 if (!updateDefaultHomeNotLocked(userId)) {
20185 postPreferredActivityChangedBroadcast(userId);
20189 private void postPreferredActivityChangedBroadcast(int userId) {
20190 mHandler.post(() -> {
20191 final IActivityManager am = ActivityManager.getService();
20196 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
20197 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20198 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
20200 am.broadcastIntent(null, intent, null, null,
20201 0, null, null, null, android.app.AppOpsManager.OP_NONE,
20202 null, false, false, userId);
20203 } catch (RemoteException e) {
20209 public void replacePreferredActivity(IntentFilter filter, int match,
20210 ComponentName[] set, ComponentName activity, int userId) {
20211 if (filter.countActions() != 1) {
20212 throw new IllegalArgumentException(
20213 "replacePreferredActivity expects filter to have only 1 action.");
20215 if (filter.countDataAuthorities() != 0
20216 || filter.countDataPaths() != 0
20217 || filter.countDataSchemes() > 1
20218 || filter.countDataTypes() != 0) {
20219 throw new IllegalArgumentException(
20220 "replacePreferredActivity expects filter to have no data authorities, " +
20221 "paths, or types; and at most one scheme.");
20224 final int callingUid = Binder.getCallingUid();
20225 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20226 true /* requireFullPermission */, false /* checkShell */,
20227 "replace preferred activity");
20228 if (mContext.checkCallingOrSelfPermission(
20229 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20230 != PackageManager.PERMISSION_GRANTED) {
20231 synchronized (mPackages) {
20232 if (getUidTargetSdkVersionLockedLPr(callingUid)
20233 < Build.VERSION_CODES.FROYO) {
20234 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
20235 + Binder.getCallingUid());
20239 mContext.enforceCallingOrSelfPermission(
20240 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20243 synchronized (mPackages) {
20244 final PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
20246 // Get all of the existing entries that exactly match this filter.
20247 final ArrayList<PreferredActivity> existing = pir.findFilters(filter);
20248 if (existing != null && existing.size() == 1) {
20249 final PreferredActivity cur = existing.get(0);
20250 if (DEBUG_PREFERRED) {
20251 Slog.i(TAG, "Checking replace of preferred:");
20252 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
20253 if (!cur.mPref.mAlways) {
20254 Slog.i(TAG, " -- CUR; not mAlways!");
20256 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch);
20257 Slog.i(TAG, " -- CUR: mSet="
20258 + Arrays.toString(cur.mPref.mSetComponents));
20259 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent);
20260 Slog.i(TAG, " -- NEW: mMatch="
20261 + (match&IntentFilter.MATCH_CATEGORY_MASK));
20262 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set));
20263 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString());
20266 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
20267 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
20268 && cur.mPref.sameSet(set)) {
20269 // Setting the preferred activity to what it happens to be already
20270 if (DEBUG_PREFERRED) {
20271 Slog.i(TAG, "Replacing with same preferred activity "
20272 + cur.mPref.mShortComponent + " for user "
20274 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
20279 if (existing != null) {
20280 if (DEBUG_PREFERRED) {
20281 Slog.i(TAG, existing.size() + " existing preferred matches for:");
20282 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
20284 for (int i = existing.size() - 1; i >= 0; --i) {
20285 final PreferredActivity pa = existing.get(i);
20286 if (DEBUG_PREFERRED) {
20287 Slog.i(TAG, "Removing existing preferred activity "
20288 + pa.mPref.mComponent + ":");
20289 pa.dump(new LogPrinter(Log.INFO, TAG), " ");
20291 pir.removeFilter(pa);
20296 addPreferredActivityInternal(filter, match, set, activity, true, userId,
20297 "Replacing preferred");
20301 public void clearPackagePreferredActivities(String packageName) {
20302 final int callingUid = Binder.getCallingUid();
20303 if (getInstantAppPackageName(callingUid) != null) {
20307 synchronized (mPackages) {
20308 PackageParser.Package pkg = mPackages.get(packageName);
20309 if (pkg == null || !isCallerSameApp(packageName, callingUid)) {
20310 if (mContext.checkCallingOrSelfPermission(
20311 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20312 != PackageManager.PERMISSION_GRANTED) {
20313 if (getUidTargetSdkVersionLockedLPr(callingUid)
20314 < Build.VERSION_CODES.FROYO) {
20315 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
20319 mContext.enforceCallingOrSelfPermission(
20320 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20323 final PackageSetting ps = mSettings.getPackageLPr(packageName);
20325 && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
20329 int callingUserId = UserHandle.getCallingUserId();
20330 final SparseBooleanArray changedUsers = new SparseBooleanArray();
20331 clearPackagePreferredActivitiesLPw(packageName, changedUsers, callingUserId);
20332 if (changedUsers.size() > 0) {
20333 updateDefaultHomeNotLocked(changedUsers);
20334 postPreferredActivityChangedBroadcast(callingUserId);
20335 synchronized (mPackages) {
20336 scheduleWritePackageRestrictionsLocked(callingUserId);
20341 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20342 @GuardedBy("mPackages")
20343 private void clearPackagePreferredActivitiesLPw(String packageName,
20344 @NonNull SparseBooleanArray outUserChanged, int userId) {
20345 ArrayList<PreferredActivity> removed = null;
20346 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20347 final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
20348 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20349 if (userId != UserHandle.USER_ALL && userId != thisUserId) {
20352 Iterator<PreferredActivity> it = pir.filterIterator();
20353 while (it.hasNext()) {
20354 PreferredActivity pa = it.next();
20355 // Mark entry for removal only if it matches the package name
20356 // and the entry is of type "always".
20357 if (packageName == null ||
20358 (pa.mPref.mComponent.getPackageName().equals(packageName)
20359 && pa.mPref.mAlways)) {
20360 if (removed == null) {
20361 removed = new ArrayList<>();
20366 if (removed != null) {
20367 for (int j=0; j<removed.size(); j++) {
20368 PreferredActivity pa = removed.get(j);
20369 pir.removeFilter(pa);
20371 outUserChanged.put(thisUserId, true);
20376 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20377 @GuardedBy("mPackages")
20378 private void clearIntentFilterVerificationsLPw(int userId) {
20379 final int packageCount = mPackages.size();
20380 for (int i = 0; i < packageCount; i++) {
20381 PackageParser.Package pkg = mPackages.valueAt(i);
20382 clearIntentFilterVerificationsLPw(pkg.packageName, userId);
20386 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20387 @GuardedBy("mPackages")
20388 void clearIntentFilterVerificationsLPw(String packageName, int userId) {
20389 if (userId == UserHandle.USER_ALL) {
20390 if (mSettings.removeIntentFilterVerificationLPw(packageName,
20391 sUserManager.getUserIds())) {
20392 for (int oneUserId : sUserManager.getUserIds()) {
20393 scheduleWritePackageRestrictionsLocked(oneUserId);
20397 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
20398 scheduleWritePackageRestrictionsLocked(userId);
20403 /** Clears state for all users, and touches intent filter verification policy */
20404 void clearDefaultBrowserIfNeeded(String packageName) {
20405 for (int oneUserId : sUserManager.getUserIds()) {
20406 clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
20410 private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
20411 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
20412 if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
20413 if (packageName.equals(defaultBrowserPackageName)) {
20414 setDefaultBrowserPackageName(null, userId);
20420 public void resetApplicationPreferences(int userId) {
20421 mContext.enforceCallingOrSelfPermission(
20422 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20423 final long identity = Binder.clearCallingIdentity();
20426 final SparseBooleanArray changedUsers = new SparseBooleanArray();
20427 clearPackagePreferredActivitiesLPw(null, changedUsers, userId);
20428 if (changedUsers.size() > 0) {
20429 postPreferredActivityChangedBroadcast(userId);
20431 synchronized (mPackages) {
20432 mSettings.applyDefaultPreferredAppsLPw(userId);
20433 clearIntentFilterVerificationsLPw(userId);
20434 primeDomainVerificationsLPw(userId);
20435 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
20437 updateDefaultHomeNotLocked(userId);
20438 // TODO: We have to reset the default SMS and Phone. This requires
20439 // significant refactoring to keep all default apps in the package
20440 // manager (cleaner but more work) or have the services provide
20441 // callbacks to the package manager to request a default app reset.
20442 setDefaultBrowserPackageName(null, userId);
20443 resetNetworkPolicies(userId);
20444 synchronized (mPackages) {
20445 scheduleWritePackageRestrictionsLocked(userId);
20448 Binder.restoreCallingIdentity(identity);
20453 public int getPreferredActivities(List<IntentFilter> outFilters,
20454 List<ComponentName> outActivities, String packageName) {
20455 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20459 final int userId = UserHandle.getCallingUserId();
20461 synchronized (mPackages) {
20462 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
20464 final Iterator<PreferredActivity> it = pir.filterIterator();
20465 while (it.hasNext()) {
20466 final PreferredActivity pa = it.next();
20467 if (packageName == null
20468 || (pa.mPref.mComponent.getPackageName().equals(packageName)
20469 && pa.mPref.mAlways)) {
20470 if (outFilters != null) {
20471 outFilters.add(new IntentFilter(pa));
20473 if (outActivities != null) {
20474 outActivities.add(pa.mPref.mComponent);
20485 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
20487 int callingUid = Binder.getCallingUid();
20488 if (callingUid != Process.SYSTEM_UID) {
20489 throw new SecurityException(
20490 "addPersistentPreferredActivity can only be run by the system");
20492 if (filter.countActions() == 0) {
20493 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
20496 if (DEBUG_PREFERRED) {
20497 Slog.i(TAG, "Adding persistent preferred activity " + activity
20498 + " for user " + userId + ":");
20499 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
20501 synchronized (mPackages) {
20502 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
20503 new PersistentPreferredActivity(filter, activity));
20504 scheduleWritePackageRestrictionsLocked(userId);
20506 updateDefaultHomeNotLocked(userId);
20507 postPreferredActivityChangedBroadcast(userId);
20511 public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
20512 int callingUid = Binder.getCallingUid();
20513 if (callingUid != Process.SYSTEM_UID) {
20514 throw new SecurityException(
20515 "clearPackagePersistentPreferredActivities can only be run by the system");
20517 ArrayList<PersistentPreferredActivity> removed = null;
20518 boolean changed = false;
20519 synchronized (mPackages) {
20520 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
20521 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
20522 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
20524 if (userId != thisUserId) {
20527 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
20528 while (it.hasNext()) {
20529 PersistentPreferredActivity ppa = it.next();
20530 // Mark entry for removal only if it matches the package name.
20531 if (ppa.mComponent.getPackageName().equals(packageName)) {
20532 if (removed == null) {
20533 removed = new ArrayList<>();
20538 if (removed != null) {
20539 for (int j=0; j<removed.size(); j++) {
20540 PersistentPreferredActivity ppa = removed.get(j);
20541 ppir.removeFilter(ppa);
20548 updateDefaultHomeNotLocked(userId);
20549 postPreferredActivityChangedBroadcast(userId);
20550 synchronized (mPackages) {
20551 scheduleWritePackageRestrictionsLocked(userId);
20557 * Common machinery for picking apart a restored XML blob and passing
20558 * it to a caller-supplied functor to be applied to the running system.
20560 private void restoreFromXml(XmlPullParser parser, int userId,
20561 String expectedStartTag, BlobXmlRestorer functor)
20562 throws IOException, XmlPullParserException {
20564 while ((type = parser.next()) != XmlPullParser.START_TAG
20565 && type != XmlPullParser.END_DOCUMENT) {
20567 if (type != XmlPullParser.START_TAG) {
20568 // oops didn't find a start tag?!
20569 if (DEBUG_BACKUP) {
20570 Slog.e(TAG, "Didn't find start tag during restore");
20574 // this is supposed to be TAG_PREFERRED_BACKUP
20575 if (!expectedStartTag.equals(parser.getName())) {
20576 if (DEBUG_BACKUP) {
20577 Slog.e(TAG, "Found unexpected tag " + parser.getName());
20582 // skip interfering stuff, then we're aligned with the backing implementation
20583 while ((type = parser.next()) == XmlPullParser.TEXT) { }
20584 functor.apply(parser, userId);
20587 private interface BlobXmlRestorer {
20588 void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
20592 * Non-Binder method, support for the backup/restore mechanism: write the
20593 * full set of preferred activities in its canonical XML format. Returns the
20594 * XML output as a byte array, or null if there is none.
20597 public byte[] getPreferredActivityBackup(int userId) {
20598 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20599 throw new SecurityException("Only the system may call getPreferredActivityBackup()");
20602 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20604 final XmlSerializer serializer = new FastXmlSerializer();
20605 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20606 serializer.startDocument(null, true);
20607 serializer.startTag(null, TAG_PREFERRED_BACKUP);
20609 synchronized (mPackages) {
20610 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
20613 serializer.endTag(null, TAG_PREFERRED_BACKUP);
20614 serializer.endDocument();
20615 serializer.flush();
20616 } catch (Exception e) {
20617 if (DEBUG_BACKUP) {
20618 Slog.e(TAG, "Unable to write preferred activities for backup", e);
20623 return dataStream.toByteArray();
20627 public void restorePreferredActivities(byte[] backup, int userId) {
20628 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20629 throw new SecurityException("Only the system may call restorePreferredActivities()");
20633 final XmlPullParser parser = Xml.newPullParser();
20634 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20635 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
20636 (readParser, readUserId) -> {
20637 synchronized (mPackages) {
20638 mSettings.readPreferredActivitiesLPw(readParser, readUserId);
20640 updateDefaultHomeNotLocked(readUserId);
20642 } catch (Exception e) {
20643 if (DEBUG_BACKUP) {
20644 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20650 * Non-Binder method, support for the backup/restore mechanism: write the
20651 * default browser (etc) settings in its canonical XML format. Returns the default
20652 * browser XML representation as a byte array, or null if there is none.
20655 public byte[] getDefaultAppsBackup(int userId) {
20656 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20657 throw new SecurityException("Only the system may call getDefaultAppsBackup()");
20660 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20662 final XmlSerializer serializer = new FastXmlSerializer();
20663 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20664 serializer.startDocument(null, true);
20665 serializer.startTag(null, TAG_DEFAULT_APPS);
20667 synchronized (mPackages) {
20668 mSettings.writeDefaultAppsLPr(serializer, userId);
20671 serializer.endTag(null, TAG_DEFAULT_APPS);
20672 serializer.endDocument();
20673 serializer.flush();
20674 } catch (Exception e) {
20675 if (DEBUG_BACKUP) {
20676 Slog.e(TAG, "Unable to write default apps for backup", e);
20681 return dataStream.toByteArray();
20685 public void restoreDefaultApps(byte[] backup, int userId) {
20686 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20687 throw new SecurityException("Only the system may call restoreDefaultApps()");
20691 final XmlPullParser parser = Xml.newPullParser();
20692 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20693 restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
20694 (parser1, userId1) -> {
20695 String defaultBrowser;
20696 synchronized (mPackages) {
20697 mSettings.readDefaultAppsLPw(parser1, userId1);
20698 defaultBrowser = mSettings.removeDefaultBrowserPackageNameLPw(userId1);
20700 if (defaultBrowser != null) {
20701 PackageManagerInternal.DefaultBrowserProvider provider;
20702 synchronized (mPackages) {
20703 provider = mDefaultBrowserProvider;
20705 provider.setDefaultBrowser(defaultBrowser, userId1);
20708 } catch (Exception e) {
20709 if (DEBUG_BACKUP) {
20710 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
20716 public byte[] getIntentFilterVerificationBackup(int userId) {
20717 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20718 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
20721 ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20723 final XmlSerializer serializer = new FastXmlSerializer();
20724 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20725 serializer.startDocument(null, true);
20726 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
20728 synchronized (mPackages) {
20729 mSettings.writeAllDomainVerificationsLPr(serializer, userId);
20732 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
20733 serializer.endDocument();
20734 serializer.flush();
20735 } catch (Exception e) {
20736 if (DEBUG_BACKUP) {
20737 Slog.e(TAG, "Unable to write default apps for backup", e);
20742 return dataStream.toByteArray();
20746 public void restoreIntentFilterVerification(byte[] backup, int userId) {
20747 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20748 throw new SecurityException("Only the system may call restorePreferredActivities()");
20752 final XmlPullParser parser = Xml.newPullParser();
20753 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20754 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
20755 (parser1, userId1) -> {
20756 synchronized (mPackages) {
20757 mSettings.readAllDomainVerificationsLPr(parser1, userId1);
20758 mSettings.writeLPr();
20761 } catch (Exception e) {
20762 if (DEBUG_BACKUP) {
20763 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20769 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
20770 int sourceUserId, int targetUserId, int flags) {
20771 mContext.enforceCallingOrSelfPermission(
20772 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20773 int callingUid = Binder.getCallingUid();
20774 enforceOwnerRights(ownerPackage, callingUid);
20775 PackageManagerServiceUtils.enforceShellRestriction(
20776 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20777 if (intentFilter.countActions() == 0) {
20778 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
20781 synchronized (mPackages) {
20782 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
20783 ownerPackage, targetUserId, flags);
20784 CrossProfileIntentResolver resolver =
20785 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20786 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
20787 // We have all those whose filter is equal. Now checking if the rest is equal as well.
20788 if (existing != null) {
20789 int size = existing.size();
20790 for (int i = 0; i < size; i++) {
20791 if (newFilter.equalsIgnoreFilter(existing.get(i))) {
20796 resolver.addFilter(newFilter);
20797 scheduleWritePackageRestrictionsLocked(sourceUserId);
20802 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
20803 mContext.enforceCallingOrSelfPermission(
20804 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20805 final int callingUid = Binder.getCallingUid();
20806 enforceOwnerRights(ownerPackage, callingUid);
20807 PackageManagerServiceUtils.enforceShellRestriction(
20808 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20809 synchronized (mPackages) {
20810 CrossProfileIntentResolver resolver =
20811 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20812 ArraySet<CrossProfileIntentFilter> set =
20813 new ArraySet<>(resolver.filterSet());
20814 for (CrossProfileIntentFilter filter : set) {
20815 if (filter.getOwnerPackage().equals(ownerPackage)) {
20816 resolver.removeFilter(filter);
20819 scheduleWritePackageRestrictionsLocked(sourceUserId);
20823 // Enforcing that callingUid is owning pkg on userId
20824 private void enforceOwnerRights(String pkg, int callingUid) {
20825 // The system owns everything.
20826 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
20829 final int callingUserId = UserHandle.getUserId(callingUid);
20830 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
20832 throw new IllegalArgumentException("Unknown package " + pkg + " on user "
20835 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
20836 throw new SecurityException("Calling uid " + callingUid
20837 + " does not own package " + pkg);
20842 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
20843 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20846 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
20850 * Send a {@code PackageInstaller.ACTION_SESSION_UPDATED} broadcast intent, containing
20851 * the {@code sessionInfo} in the extra field {@code PackageInstaller.EXTRA_SESSION}.
20853 public void sendSessionUpdatedBroadcast(PackageInstaller.SessionInfo sessionInfo,
20855 if (TextUtils.isEmpty(sessionInfo.installerPackageName)) {
20858 Intent sessionUpdatedIntent = new Intent(PackageInstaller.ACTION_SESSION_UPDATED)
20859 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
20860 .setPackage(sessionInfo.installerPackageName);
20861 mContext.sendBroadcastAsUser(sessionUpdatedIntent, UserHandle.of(userId));
20864 public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
20865 UserManagerService ums = UserManagerService.getInstance();
20867 final UserInfo parent = ums.getProfileParent(userId);
20868 final int launcherUid = (parent != null) ? parent.id : userId;
20869 final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
20870 if (launcherComponent != null) {
20871 Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
20872 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
20873 .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
20874 .setPackage(launcherComponent.getPackageName());
20875 mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
20877 // TODO(b/122900055) Change/Remove this and replace with new permission role.
20878 if (mAppPredictionServicePackage != null) {
20879 Intent predictorIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
20880 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
20881 .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
20882 .setPackage(mAppPredictionServicePackage);
20883 mContext.sendBroadcastAsUser(predictorIntent, UserHandle.of(launcherUid));
20889 * Report the 'Home' activity which is currently set as "always use this one". If non is set
20890 * then reports the most likely home activity or null if there are more than one.
20892 private ComponentName getDefaultHomeActivity(int userId) {
20893 List<ResolveInfo> allHomeCandidates = new ArrayList<>();
20894 ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
20899 // Find the launcher with the highest priority and return that component if there are no
20900 // other home activity with the same priority.
20901 int lastPriority = Integer.MIN_VALUE;
20902 ComponentName lastComponent = null;
20903 final int size = allHomeCandidates.size();
20904 for (int i = 0; i < size; i++) {
20905 final ResolveInfo ri = allHomeCandidates.get(i);
20906 if (ri.priority > lastPriority) {
20907 lastComponent = ri.activityInfo.getComponentName();
20908 lastPriority = ri.priority;
20909 } else if (ri.priority == lastPriority) {
20910 // Two components found with same priority.
20911 lastComponent = null;
20914 return lastComponent;
20917 private Intent getHomeIntent() {
20918 Intent intent = new Intent(Intent.ACTION_MAIN);
20919 intent.addCategory(Intent.CATEGORY_HOME);
20920 intent.addCategory(Intent.CATEGORY_DEFAULT);
20924 private IntentFilter getHomeFilter() {
20925 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
20926 filter.addCategory(Intent.CATEGORY_HOME);
20927 filter.addCategory(Intent.CATEGORY_DEFAULT);
20931 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
20933 Intent intent = getHomeIntent();
20934 List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
20935 PackageManager.GET_META_DATA, userId);
20936 allHomeCandidates.clear();
20937 if (resolveInfos == null) {
20940 allHomeCandidates.addAll(resolveInfos);
20942 PackageManagerInternal.DefaultHomeProvider provider;
20943 synchronized (mPackages) {
20944 provider = mDefaultHomeProvider;
20946 if (provider == null) {
20947 Slog.e(TAG, "mDefaultHomeProvider is null");
20950 String packageName = provider.getDefaultHome(userId);
20951 if (packageName == null) {
20954 int resolveInfosSize = resolveInfos.size();
20955 for (int i = 0; i < resolveInfosSize; i++) {
20956 ResolveInfo resolveInfo = resolveInfos.get(i);
20958 if (resolveInfo.activityInfo != null && TextUtils.equals(
20959 resolveInfo.activityInfo.packageName, packageName)) {
20960 return new ComponentName(resolveInfo.activityInfo.packageName,
20961 resolveInfo.activityInfo.name);
20967 /** <b>must not hold {@link #mPackages}</b> */
20968 private void updateDefaultHomeNotLocked(SparseBooleanArray userIds) {
20969 if (Thread.holdsLock(mPackages)) {
20970 Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
20971 + " is holding mPackages", new Throwable());
20973 for (int i = userIds.size() - 1; i >= 0; --i) {
20974 final int userId = userIds.keyAt(i);
20975 updateDefaultHomeNotLocked(userId);
20980 * <b>must not hold {@link #mPackages}</b>
20982 * @return Whether the ACTION_PREFERRED_ACTIVITY_CHANGED broadcast has been scheduled.
20984 private boolean updateDefaultHomeNotLocked(int userId) {
20985 if (Thread.holdsLock(mPackages)) {
20986 Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
20987 + " is holding mPackages", new Throwable());
20989 if (!mSystemReady) {
20990 // We might get called before system is ready because of package changes etc, but
20991 // finding preferred activity depends on settings provider, so we ignore the update
20995 final Intent intent = getHomeIntent();
20996 final List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
20997 PackageManager.GET_META_DATA, userId);
20998 final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(
20999 intent, null, 0, resolveInfos, 0, true, false, false, userId);
21000 final String packageName = preferredResolveInfo != null
21001 && preferredResolveInfo.activityInfo != null
21002 ? preferredResolveInfo.activityInfo.packageName : null;
21003 final PackageManagerInternal.DefaultHomeProvider provider;
21004 synchronized (mPackages) {
21005 provider = mDefaultHomeProvider;
21007 if (provider == null) {
21008 Slog.e(TAG, "Default home provider has not been set");
21011 final String currentPackageName = provider.getDefaultHome(userId);
21012 if (TextUtils.equals(currentPackageName, packageName)) {
21015 final String[] callingPackages = getPackagesForUid(Binder.getCallingUid());
21016 if (callingPackages != null && ArrayUtils.contains(callingPackages,
21017 mRequiredPermissionControllerPackage)) {
21018 // PermissionController manages default home directly.
21021 provider.setDefaultHomeAsync(packageName, userId, (successful) -> {
21023 postPreferredActivityChangedBroadcast(userId);
21030 public void setHomeActivity(ComponentName comp, int userId) {
21031 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21034 ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
21035 getHomeActivitiesAsUser(homeActivities, userId);
21037 boolean found = false;
21039 final int size = homeActivities.size();
21040 final ComponentName[] set = new ComponentName[size];
21041 for (int i = 0; i < size; i++) {
21042 final ResolveInfo candidate = homeActivities.get(i);
21043 final ActivityInfo info = candidate.activityInfo;
21044 final ComponentName activityName = new ComponentName(info.packageName, info.name);
21045 set[i] = activityName;
21046 if (!found && activityName.equals(comp)) {
21051 throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
21054 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
21055 set, comp, userId);
21058 private @Nullable String getSetupWizardPackageName() {
21059 final Intent intent = new Intent(Intent.ACTION_MAIN);
21060 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
21062 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21063 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21064 | MATCH_DISABLED_COMPONENTS,
21065 UserHandle.myUserId());
21066 if (matches.size() == 1) {
21067 return matches.get(0).getComponentInfo().packageName;
21069 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
21070 + ": matches=" + matches);
21075 private @Nullable String getStorageManagerPackageName() {
21076 final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
21078 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21079 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21080 | MATCH_DISABLED_COMPONENTS,
21081 UserHandle.myUserId());
21082 if (matches.size() == 1) {
21083 return matches.get(0).getComponentInfo().packageName;
21085 Slog.e(TAG, "There should probably be exactly one storage manager; found "
21086 + matches.size() + ": matches=" + matches);
21092 public String getSystemTextClassifierPackageName() {
21093 return mContext.getString(R.string.config_defaultTextClassifierPackage);
21097 public @Nullable String getAttentionServicePackageName() {
21098 final String flattenedComponentName =
21099 mContext.getString(R.string.config_defaultAttentionService);
21100 if (flattenedComponentName != null) {
21101 ComponentName componentName = ComponentName.unflattenFromString(flattenedComponentName);
21102 if (componentName != null && componentName.getPackageName() != null) {
21103 return componentName.getPackageName();
21109 private @Nullable String getDocumenterPackageName() {
21110 final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
21111 intent.addCategory(Intent.CATEGORY_OPENABLE);
21112 intent.setType("*/*");
21113 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
21115 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, resolvedType,
21116 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21117 | MATCH_DISABLED_COMPONENTS,
21118 UserHandle.myUserId());
21119 if (matches.size() == 1) {
21120 return matches.get(0).getComponentInfo().packageName;
21122 Slog.e(TAG, "There should probably be exactly one documenter; found "
21123 + matches.size() + ": matches=" + matches);
21129 public String getWellbeingPackageName() {
21130 return mContext.getString(R.string.config_defaultWellbeingPackage);
21134 public String getAppPredictionServicePackageName() {
21135 String flattenedAppPredictionServiceComponentName =
21136 mContext.getString(R.string.config_defaultAppPredictionService);
21137 if (flattenedAppPredictionServiceComponentName == null) {
21140 ComponentName appPredictionServiceComponentName =
21141 ComponentName.unflattenFromString(flattenedAppPredictionServiceComponentName);
21142 if (appPredictionServiceComponentName == null) {
21145 return appPredictionServiceComponentName.getPackageName();
21149 public String getSystemCaptionsServicePackageName() {
21150 String flattenedSystemCaptionsServiceComponentName =
21151 mContext.getString(R.string.config_defaultSystemCaptionsService);
21153 if (TextUtils.isEmpty(flattenedSystemCaptionsServiceComponentName)) {
21157 ComponentName systemCaptionsServiceComponentName =
21158 ComponentName.unflattenFromString(flattenedSystemCaptionsServiceComponentName);
21159 if (systemCaptionsServiceComponentName == null) {
21162 return systemCaptionsServiceComponentName.getPackageName();
21165 public String getIncidentReportApproverPackageName() {
21166 return mContext.getString(R.string.config_incidentReportApproverPackage);
21170 public void setApplicationEnabledSetting(String appPackageName,
21171 int newState, int flags, int userId, String callingPackage) {
21172 if (!sUserManager.exists(userId)) return;
21173 if (callingPackage == null) {
21174 callingPackage = Integer.toString(Binder.getCallingUid());
21176 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
21180 public void setUpdateAvailable(String packageName, boolean updateAvailable) {
21181 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
21182 synchronized (mPackages) {
21183 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
21184 if (pkgSetting != null) {
21185 pkgSetting.setUpdateAvailable(updateAvailable);
21191 public void setComponentEnabledSetting(ComponentName componentName,
21192 int newState, int flags, int userId) {
21193 if (!sUserManager.exists(userId)) return;
21194 setEnabledSetting(componentName.getPackageName(),
21195 componentName.getClassName(), newState, flags, userId, null);
21198 private void setEnabledSetting(final String packageName, String className, int newState,
21199 final int flags, int userId, String callingPackage) {
21200 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
21201 || newState == COMPONENT_ENABLED_STATE_ENABLED
21202 || newState == COMPONENT_ENABLED_STATE_DISABLED
21203 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
21204 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
21205 throw new IllegalArgumentException("Invalid new component state: "
21208 PackageSetting pkgSetting;
21209 final int callingUid = Binder.getCallingUid();
21210 final int permission;
21211 if (callingUid == Process.SYSTEM_UID) {
21212 permission = PackageManager.PERMISSION_GRANTED;
21214 permission = mContext.checkCallingOrSelfPermission(
21215 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
21217 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
21218 false /* requireFullPermission */, true /* checkShell */, "set enabled");
21219 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
21220 boolean sendNow = false;
21221 boolean isApp = (className == null);
21222 final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
21223 String componentName = isApp ? packageName : className;
21224 ArrayList<String> components;
21227 synchronized (mPackages) {
21228 pkgSetting = mSettings.mPackages.get(packageName);
21229 if (pkgSetting == null) {
21230 if (!isCallerInstantApp) {
21231 if (className == null) {
21232 throw new IllegalArgumentException("Unknown package: " + packageName);
21234 throw new IllegalArgumentException(
21235 "Unknown component: " + packageName + "/" + className);
21237 // throw SecurityException to prevent leaking package information
21238 throw new SecurityException(
21239 "Attempt to change component state; "
21240 + "pid=" + Binder.getCallingPid()
21241 + ", uid=" + callingUid
21242 + (className == null
21243 ? ", package=" + packageName
21244 : ", component=" + packageName + "/" + className));
21249 // Limit who can change which apps
21250 if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
21251 // Don't allow apps that don't have permission to modify other apps
21252 if (!allowedByPermission
21253 || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
21254 throw new SecurityException(
21255 "Attempt to change component state; "
21256 + "pid=" + Binder.getCallingPid()
21257 + ", uid=" + callingUid
21258 + (className == null
21259 ? ", package=" + packageName
21260 : ", component=" + packageName + "/" + className));
21262 // Don't allow changing protected packages.
21263 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
21264 throw new SecurityException("Cannot disable a protected package: " + packageName);
21267 // Only allow apps with CHANGE_COMPONENT_ENABLED_STATE permission to change hidden
21268 // app details activity
21269 if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)
21270 && !allowedByPermission) {
21271 throw new SecurityException("Cannot disable a system-generated component");
21274 synchronized (mPackages) {
21275 if (callingUid == Process.SHELL_UID
21276 && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
21277 // Shell can only change whole packages between ENABLED and DISABLED_USER states
21278 // unless it is a test package.
21279 int oldState = pkgSetting.getEnabled(userId);
21280 if (className == null
21282 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
21283 || oldState == COMPONENT_ENABLED_STATE_DEFAULT
21284 || oldState == COMPONENT_ENABLED_STATE_ENABLED)
21286 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
21287 || newState == COMPONENT_ENABLED_STATE_DEFAULT
21288 || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
21291 throw new SecurityException(
21292 "Shell cannot change component state for " + packageName + "/"
21293 + className + " to " + newState);
21297 if (className == null) {
21298 // We're dealing with an application/package level state change
21299 synchronized (mPackages) {
21300 if (pkgSetting.getEnabled(userId) == newState) {
21305 // If we're enabling a system stub, there's a little more work to do.
21306 // Prior to enabling the package, we need to decompress the APK(s) to the
21307 // data partition and then replace the version on the system partition.
21308 final PackageParser.Package deletedPkg = pkgSetting.pkg;
21309 final boolean isSystemStub = deletedPkg.isStub
21310 && deletedPkg.isSystem();
21312 && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
21313 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
21314 if (!enableCompressedPackage(deletedPkg)) {
21318 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
21319 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
21320 // Don't care about who enables an app.
21321 callingPackage = null;
21323 synchronized (mPackages) {
21324 pkgSetting.setEnabled(newState, userId, callingPackage);
21327 synchronized (mPackages) {
21328 // We're dealing with a component level state change
21329 // First, verify that this is a valid class name.
21330 PackageParser.Package pkg = pkgSetting.pkg;
21331 if (pkg == null || !pkg.hasComponentClassName(className)) {
21333 pkg.applicationInfo.targetSdkVersion >=
21334 Build.VERSION_CODES.JELLY_BEAN) {
21335 throw new IllegalArgumentException("Component class " + className
21336 + " does not exist in " + packageName);
21338 Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
21339 + className + " does not exist in " + packageName);
21342 switch (newState) {
21343 case COMPONENT_ENABLED_STATE_ENABLED:
21344 if (!pkgSetting.enableComponentLPw(className, userId)) {
21348 case COMPONENT_ENABLED_STATE_DISABLED:
21349 if (!pkgSetting.disableComponentLPw(className, userId)) {
21353 case COMPONENT_ENABLED_STATE_DEFAULT:
21354 if (!pkgSetting.restoreComponentLPw(className, userId)) {
21359 Slog.e(TAG, "Invalid new component state: " + newState);
21364 synchronized (mPackages) {
21365 scheduleWritePackageRestrictionsLocked(userId);
21366 updateSequenceNumberLP(pkgSetting, new int[] { userId });
21367 final long callingId = Binder.clearCallingIdentity();
21369 updateInstantAppInstallerLocked(packageName);
21371 Binder.restoreCallingIdentity(callingId);
21373 components = mPendingBroadcasts.get(userId, packageName);
21374 final boolean newPackage = components == null;
21376 components = new ArrayList<>();
21378 if (!components.contains(componentName)) {
21379 components.add(componentName);
21381 if ((flags&PackageManager.DONT_KILL_APP) == 0) {
21383 // Purge entry from pending broadcast list if another one exists already
21384 // since we are sending one right away.
21385 mPendingBroadcasts.remove(userId, packageName);
21388 mPendingBroadcasts.put(userId, packageName, components);
21390 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
21391 // Schedule a message - if it has been a "reasonably long time" since the
21392 // service started, send the broadcast with a delay of one second to avoid
21393 // delayed reactions from the receiver, else keep the default ten second delay
21394 // to avoid extreme thrashing on service startup.
21395 final long broadcastDelay = SystemClock.uptimeMillis() > mServiceStartWithDelay
21397 : BROADCAST_DELAY_DURING_STARTUP;
21398 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, broadcastDelay);
21403 long callingId = Binder.clearCallingIdentity();
21406 int packageUid = UserHandle.getUid(userId, pkgSetting.appId);
21407 sendPackageChangedBroadcast(packageName,
21408 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
21411 Binder.restoreCallingIdentity(callingId);
21416 public void flushPackageRestrictionsAsUser(int userId) {
21417 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21420 if (!sUserManager.exists(userId)) {
21423 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
21424 false /* checkShell */, "flushPackageRestrictions");
21425 synchronized (mPackages) {
21426 mSettings.writePackageRestrictionsLPr(userId);
21427 mDirtyUsers.remove(userId);
21428 if (mDirtyUsers.isEmpty()) {
21429 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
21434 private void sendPackageChangedBroadcast(String packageName,
21435 boolean killFlag, ArrayList<String> componentNames, int packageUid) {
21437 Log.v(TAG, "Sending package changed: package=" + packageName + " components="
21439 Bundle extras = new Bundle(4);
21440 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
21441 String nameList[] = new String[componentNames.size()];
21442 componentNames.toArray(nameList);
21443 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
21444 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
21445 extras.putInt(Intent.EXTRA_UID, packageUid);
21446 // If this is not reporting a change of the overall package, then only send it
21447 // to registered receivers. We don't want to launch a swath of apps for every
21448 // little component state change.
21449 final int flags = !componentNames.contains(packageName)
21450 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
21451 final int userId = UserHandle.getUserId(packageUid);
21452 final boolean isInstantApp = isInstantApp(packageName, userId);
21453 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
21454 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
21455 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null,
21456 userIds, instantUserIds);
21460 public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
21461 if (!sUserManager.exists(userId)) return;
21462 final int callingUid = Binder.getCallingUid();
21463 if (getInstantAppPackageName(callingUid) != null) {
21466 final int permission = mContext.checkCallingOrSelfPermission(
21467 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
21468 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
21469 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
21470 true /* requireFullPermission */, true /* checkShell */, "stop package");
21472 synchronized (mPackages) {
21473 final PackageSetting ps = mSettings.mPackages.get(packageName);
21474 if (!filterAppAccessLPr(ps, callingUid, userId)
21475 && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
21476 allowedByPermission, callingUid, userId)) {
21477 scheduleWritePackageRestrictionsLocked(userId);
21483 public String getInstallerPackageName(String packageName) {
21484 final int callingUid = Binder.getCallingUid();
21485 synchronized (mPackages) {
21486 final PackageSetting ps = mSettings.mPackages.get(packageName);
21487 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
21490 // InstallerPackageName for Apex is not stored in PackageManager
21491 if (ps == null && mApexManager.isApexPackage(packageName)) {
21494 return mSettings.getInstallerPackageNameLPr(packageName);
21498 public boolean isOrphaned(String packageName) {
21500 synchronized (mPackages) {
21501 if (!mPackages.containsKey(packageName)) {
21504 return mSettings.isOrphaned(packageName);
21509 public int getApplicationEnabledSetting(String packageName, int userId) {
21510 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
21511 int callingUid = Binder.getCallingUid();
21512 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
21513 false /* requireFullPermission */, false /* checkShell */, "get enabled");
21515 synchronized (mPackages) {
21516 if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
21517 return COMPONENT_ENABLED_STATE_DISABLED;
21519 return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
21524 public int getComponentEnabledSetting(@NonNull ComponentName component, int userId) {
21525 if (component == null) return COMPONENT_ENABLED_STATE_DEFAULT;
21526 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
21527 int callingUid = Binder.getCallingUid();
21528 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
21529 false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
21530 synchronized (mPackages) {
21531 if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
21532 component, TYPE_UNKNOWN, userId)) {
21533 return COMPONENT_ENABLED_STATE_DISABLED;
21535 return mSettings.getComponentEnabledSettingLPr(component, userId);
21540 public void enterSafeMode() {
21541 enforceSystemOrRoot("Only the system can request entering safe mode");
21543 if (!mSystemReady) {
21549 public void systemReady() {
21550 enforceSystemOrRoot("Only the system can claim the system is ready");
21552 mSystemReady = true;
21553 final ContentResolver resolver = mContext.getContentResolver();
21554 ContentObserver co = new ContentObserver(mHandler) {
21556 public void onChange(boolean selfChange) {
21557 final boolean ephemeralFeatureDisabled =
21558 Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0;
21559 for (int userId : UserManagerService.getInstance().getUserIds()) {
21560 final boolean instantAppsDisabledForUser =
21561 ephemeralFeatureDisabled || Secure.getIntForUser(resolver,
21562 Secure.INSTANT_APPS_ENABLED, 1, userId) == 0;
21563 mWebInstantAppsDisabled.put(userId, instantAppsDisabledForUser);
21567 mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
21568 .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
21569 false, co, UserHandle.USER_ALL);
21570 mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure
21571 .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL);
21574 // Disable any carrier apps. We do this very early in boot to prevent the apps from being
21575 // disabled after already being started.
21576 CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
21577 mContext.getContentResolver(), UserHandle.USER_SYSTEM);
21579 disableSkuSpecificApps();
21581 // Read the compatibilty setting when the system is ready.
21582 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
21583 mContext.getContentResolver(),
21584 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
21585 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
21587 if (DEBUG_SETTINGS) {
21588 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
21591 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
21593 synchronized (mPackages) {
21594 // Verify that all of the preferred activity components actually
21595 // exist. It is possible for applications to be updated and at
21596 // that point remove a previously declared activity component that
21597 // had been set as a preferred activity. We try to clean this up
21598 // the next time we encounter that preferred activity, but it is
21599 // possible for the user flow to never be able to return to that
21600 // situation so here we do a sanity check to make sure we haven't
21601 // left any junk around.
21602 ArrayList<PreferredActivity> removed = new ArrayList<>();
21603 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21604 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21606 for (PreferredActivity pa : pir.filterSet()) {
21607 if (!mComponentResolver.isActivityDefined(pa.mPref.mComponent)) {
21611 if (removed.size() > 0) {
21612 for (int r=0; r<removed.size(); r++) {
21613 PreferredActivity pa = removed.get(r);
21614 Slog.w(TAG, "Removing dangling preferred activity: "
21615 + pa.mPref.mComponent);
21616 pir.removeFilter(pa);
21618 mSettings.writePackageRestrictionsLPr(
21619 mSettings.mPreferredActivities.keyAt(i));
21623 for (int userId : UserManagerService.getInstance().getUserIds()) {
21624 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
21625 grantPermissionsUserIds = ArrayUtils.appendInt(
21626 grantPermissionsUserIds, userId);
21631 sUserManager.systemReady();
21632 // If we upgraded grant all default permissions before kicking off.
21633 for (int userId : grantPermissionsUserIds) {
21634 mDefaultPermissionPolicy.grantDefaultPermissions(userId);
21637 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
21638 // If we did not grant default permissions, we preload from this the
21639 // default permission exceptions lazily to ensure we don't hit the
21640 // disk on a new user creation.
21641 mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
21644 // Now that we've scanned all packages, and granted any default
21645 // permissions, ensure permissions are updated. Beware of dragons if you
21646 // try optimizing this.
21647 synchronized (mPackages) {
21648 mPermissionManager.updateAllPermissions(
21649 StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
21650 mPermissionCallback);
21652 final PermissionPolicyInternal permissionPolicyInternal =
21653 LocalServices.getService(PermissionPolicyInternal.class);
21654 permissionPolicyInternal.setOnInitializedCallback(userId -> {
21655 // The SDK updated case is already handled when we run during the ctor.
21656 synchronized (mPackages) {
21657 mPermissionManager.updateAllPermissions(
21658 StorageManager.UUID_PRIVATE_INTERNAL, false /*sdkUpdated*/,
21659 mPackages.values(), mPermissionCallback);
21664 // Watch for external volumes that come and go over time
21665 final StorageManager storage = mContext.getSystemService(StorageManager.class);
21666 storage.registerListener(mStorageListener);
21668 mInstallerService.systemReady();
21669 mApexManager.systemReady();
21670 mPackageDexOptimizer.systemReady();
21672 getStorageManagerInternal().addExternalStoragePolicy(
21673 new StorageManagerInternal.ExternalStorageMountPolicy() {
21675 public int getMountMode(int uid, String packageName) {
21676 if (Process.isIsolated(uid)) {
21677 return Zygote.MOUNT_EXTERNAL_NONE;
21679 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
21680 return Zygote.MOUNT_EXTERNAL_DEFAULT;
21682 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
21683 return Zygote.MOUNT_EXTERNAL_READ;
21685 return Zygote.MOUNT_EXTERNAL_WRITE;
21689 public boolean hasExternalStorage(int uid, String packageName) {
21694 // Now that we're mostly running, clean up stale users and apps
21695 sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
21696 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
21698 mPermissionManager.systemReady();
21700 if (mInstantAppResolverConnection != null) {
21701 mContext.registerReceiver(new BroadcastReceiver() {
21703 public void onReceive(Context context, Intent intent) {
21704 mInstantAppResolverConnection.optimisticBind();
21705 mContext.unregisterReceiver(this);
21707 }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
21710 mModuleInfoProvider.systemReady();
21712 // Installer service might attempt to install some packages that have been staged for
21713 // installation on reboot. Make sure this is the last component to be call since the
21714 // installation might require other components to be ready.
21715 mInstallerService.restoreAndApplyStagedSessionIfNeeded();
21718 public void waitForAppDataPrepared() {
21719 if (mPrepareAppDataFuture == null) {
21722 ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
21723 mPrepareAppDataFuture = null;
21727 public boolean isSafeMode() {
21728 // allow instant applications
21733 public boolean hasSystemUidErrors() {
21734 // allow instant applications
21735 return mHasSystemUidErrors;
21738 static String arrayToString(int[] array) {
21739 StringBuilder stringBuilder = new StringBuilder(128);
21740 stringBuilder.append('[');
21741 if (array != null) {
21742 for (int i=0; i<array.length; i++) {
21743 if (i > 0) stringBuilder.append(", ");
21744 stringBuilder.append(array[i]);
21747 stringBuilder.append(']');
21748 return stringBuilder.toString();
21752 public void onShellCommand(FileDescriptor in, FileDescriptor out,
21753 FileDescriptor err, String[] args, ShellCallback callback,
21754 ResultReceiver resultReceiver) {
21755 (new PackageManagerShellCommand(this)).exec(
21756 this, in, out, err, args, callback, resultReceiver);
21759 @SuppressWarnings("resource")
21761 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
21762 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
21764 DumpState dumpState = new DumpState();
21765 boolean fullPreferred = false;
21766 boolean checkin = false;
21768 String packageName = null;
21769 ArraySet<String> permissionNames = null;
21772 while (opti < args.length) {
21773 String opt = args[opti];
21774 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
21779 if ("-a".equals(opt)) {
21780 // Right now we only know how to print all.
21781 } else if ("-h".equals(opt)) {
21782 pw.println("Package manager dump options:");
21783 pw.println(" [-h] [-f] [--checkin] [--all-components] [cmd] ...");
21784 pw.println(" --checkin: dump for a checkin");
21785 pw.println(" -f: print details of intent filters");
21786 pw.println(" -h: print this help");
21787 pw.println(" --all-components: include all component names in package dump");
21788 pw.println(" cmd may be one of:");
21789 pw.println(" apex: list active APEXes and APEX session state");
21790 pw.println(" l[ibraries]: list known shared libraries");
21791 pw.println(" f[eatures]: list device features");
21792 pw.println(" k[eysets]: print known keysets");
21793 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
21794 pw.println(" perm[issions]: dump permissions");
21795 pw.println(" permission [name ...]: dump declaration and use of given permission");
21796 pw.println(" pref[erred]: print preferred package settings");
21797 pw.println(" preferred-xml [--full]: print preferred package settings as xml");
21798 pw.println(" prov[iders]: dump content providers");
21799 pw.println(" p[ackages]: dump installed packages");
21800 pw.println(" s[hared-users]: dump shared user IDs");
21801 pw.println(" m[essages]: print collected runtime messages");
21802 pw.println(" v[erifiers]: print package verifier info");
21803 pw.println(" d[omain-preferred-apps]: print domains preferred apps");
21804 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
21805 pw.println(" version: print database version info");
21806 pw.println(" write: write current settings now");
21807 pw.println(" installs: details about install sessions");
21808 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?");
21809 pw.println(" dexopt: dump dexopt state");
21810 pw.println(" compiler-stats: dump compiler statistics");
21811 pw.println(" service-permissions: dump permissions required by services");
21812 pw.println(" <package.name>: info about given package");
21814 } else if ("--checkin".equals(opt)) {
21816 } else if ("--all-components".equals(opt)) {
21817 dumpState.setOptionEnabled(DumpState.OPTION_DUMP_ALL_COMPONENTS);
21818 } else if ("-f".equals(opt)) {
21819 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21820 } else if ("--proto".equals(opt)) {
21824 pw.println("Unknown argument: " + opt + "; use -h for help");
21828 // Is the caller requesting to dump a particular piece of data?
21829 if (opti < args.length) {
21830 String cmd = args[opti];
21832 // Is this a package name?
21833 if ("android".equals(cmd) || cmd.contains(".")) {
21835 // When dumping a single package, we always dump all of its
21836 // filter information since the amount of data will be reasonable.
21837 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21838 } else if ("check-permission".equals(cmd)) {
21839 if (opti >= args.length) {
21840 pw.println("Error: check-permission missing permission argument");
21843 String perm = args[opti];
21845 if (opti >= args.length) {
21846 pw.println("Error: check-permission missing package argument");
21850 String pkg = args[opti];
21852 int user = UserHandle.getUserId(Binder.getCallingUid());
21853 if (opti < args.length) {
21855 user = Integer.parseInt(args[opti]);
21856 } catch (NumberFormatException e) {
21857 pw.println("Error: check-permission user argument is not a number: "
21863 // Normalize package name to handle renamed packages and static libs
21864 pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
21866 pw.println(checkPermission(perm, pkg, user));
21868 } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
21869 dumpState.setDump(DumpState.DUMP_LIBS);
21870 } else if ("f".equals(cmd) || "features".equals(cmd)) {
21871 dumpState.setDump(DumpState.DUMP_FEATURES);
21872 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
21873 if (opti >= args.length) {
21874 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
21875 | DumpState.DUMP_SERVICE_RESOLVERS
21876 | DumpState.DUMP_RECEIVER_RESOLVERS
21877 | DumpState.DUMP_CONTENT_RESOLVERS);
21879 while (opti < args.length) {
21880 String name = args[opti];
21881 if ("a".equals(name) || "activity".equals(name)) {
21882 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
21883 } else if ("s".equals(name) || "service".equals(name)) {
21884 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
21885 } else if ("r".equals(name) || "receiver".equals(name)) {
21886 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
21887 } else if ("c".equals(name) || "content".equals(name)) {
21888 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
21890 pw.println("Error: unknown resolver table type: " + name);
21896 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
21897 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
21898 } else if ("permission".equals(cmd)) {
21899 if (opti >= args.length) {
21900 pw.println("Error: permission requires permission name");
21903 permissionNames = new ArraySet<>();
21904 while (opti < args.length) {
21905 permissionNames.add(args[opti]);
21908 dumpState.setDump(DumpState.DUMP_PERMISSIONS
21909 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
21910 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
21911 dumpState.setDump(DumpState.DUMP_PREFERRED);
21912 } else if ("preferred-xml".equals(cmd)) {
21913 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
21914 if (opti < args.length && "--full".equals(args[opti])) {
21915 fullPreferred = true;
21918 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
21919 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
21920 } else if ("p".equals(cmd) || "packages".equals(cmd)) {
21921 dumpState.setDump(DumpState.DUMP_PACKAGES);
21922 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
21923 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
21924 if (opti < args.length && "noperm".equals(args[opti])) {
21925 dumpState.setOptionEnabled(DumpState.OPTION_SKIP_PERMISSIONS);
21927 } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
21928 dumpState.setDump(DumpState.DUMP_PROVIDERS);
21929 } else if ("m".equals(cmd) || "messages".equals(cmd)) {
21930 dumpState.setDump(DumpState.DUMP_MESSAGES);
21931 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
21932 dumpState.setDump(DumpState.DUMP_VERIFIERS);
21933 } else if ("i".equals(cmd) || "ifv".equals(cmd)
21934 || "intent-filter-verifiers".equals(cmd)) {
21935 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
21936 } else if ("version".equals(cmd)) {
21937 dumpState.setDump(DumpState.DUMP_VERSION);
21938 } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
21939 dumpState.setDump(DumpState.DUMP_KEYSETS);
21940 } else if ("installs".equals(cmd)) {
21941 dumpState.setDump(DumpState.DUMP_INSTALLS);
21942 } else if ("frozen".equals(cmd)) {
21943 dumpState.setDump(DumpState.DUMP_FROZEN);
21944 } else if ("volumes".equals(cmd)) {
21945 dumpState.setDump(DumpState.DUMP_VOLUMES);
21946 } else if ("dexopt".equals(cmd)) {
21947 dumpState.setDump(DumpState.DUMP_DEXOPT);
21948 } else if ("compiler-stats".equals(cmd)) {
21949 dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
21950 } else if ("changes".equals(cmd)) {
21951 dumpState.setDump(DumpState.DUMP_CHANGES);
21952 } else if ("service-permissions".equals(cmd)) {
21953 dumpState.setDump(DumpState.DUMP_SERVICE_PERMISSIONS);
21954 } else if ("write".equals(cmd)) {
21955 synchronized (mPackages) {
21956 mSettings.writeLPr();
21957 pw.println("Settings written.");
21964 pw.println("vers,1");
21968 synchronized (mPackages) {
21969 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
21971 if (dumpState.onTitlePrinted())
21973 pw.println("Database versions:");
21974 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " "));
21978 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
21980 if (dumpState.onTitlePrinted())
21982 pw.println("Verifiers:");
21983 pw.print(" Required: ");
21984 pw.print(mRequiredVerifierPackage);
21985 pw.print(" (uid=");
21986 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21987 UserHandle.USER_SYSTEM));
21989 } else if (mRequiredVerifierPackage != null) {
21990 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
21992 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21993 UserHandle.USER_SYSTEM));
21997 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
21998 packageName == null) {
21999 if (mIntentFilterVerifierComponent != null) {
22000 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
22002 if (dumpState.onTitlePrinted())
22004 pw.println("Intent Filter Verifier:");
22005 pw.print(" Using: ");
22006 pw.print(verifierPackageName);
22007 pw.print(" (uid=");
22008 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
22009 UserHandle.USER_SYSTEM));
22011 } else if (verifierPackageName != null) {
22012 pw.print("ifv,"); pw.print(verifierPackageName);
22014 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
22015 UserHandle.USER_SYSTEM));
22019 pw.println("No Intent Filter Verifier available!");
22023 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
22024 boolean printedHeader = false;
22025 final Iterator<String> it = mSharedLibraries.keySet().iterator();
22026 while (it.hasNext()) {
22027 String libName = it.next();
22028 LongSparseArray<SharedLibraryInfo> versionedLib
22029 = mSharedLibraries.get(libName);
22030 if (versionedLib == null) {
22033 final int versionCount = versionedLib.size();
22034 for (int i = 0; i < versionCount; i++) {
22035 SharedLibraryInfo libraryInfo = versionedLib.valueAt(i);
22037 if (!printedHeader) {
22038 if (dumpState.onTitlePrinted())
22040 pw.println("Libraries:");
22041 printedHeader = true;
22047 pw.print(libraryInfo.getName());
22048 if (libraryInfo.isStatic()) {
22049 pw.print(" version=" + libraryInfo.getLongVersion());
22054 if (libraryInfo.getPath() != null) {
22055 pw.print(" (jar) ");
22056 pw.print(libraryInfo.getPath());
22058 pw.print(" (apk) ");
22059 pw.print(libraryInfo.getPackageName());
22066 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
22067 if (dumpState.onTitlePrinted())
22070 pw.println("Features:");
22073 synchronized (mAvailableFeatures) {
22074 for (FeatureInfo feat : mAvailableFeatures.values()) {
22077 pw.print(feat.name);
22079 pw.println(feat.version);
22082 pw.print(feat.name);
22083 if (feat.version > 0) {
22084 pw.print(" version=");
22085 pw.print(feat.version);
22093 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
22094 mComponentResolver.dumpActivityResolvers(pw, dumpState, packageName);
22096 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
22097 mComponentResolver.dumpReceiverResolvers(pw, dumpState, packageName);
22099 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
22100 mComponentResolver.dumpServiceResolvers(pw, dumpState, packageName);
22102 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
22103 mComponentResolver.dumpProviderResolvers(pw, dumpState, packageName);
22106 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
22107 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
22108 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
22109 int user = mSettings.mPreferredActivities.keyAt(i);
22111 dumpState.getTitlePrinted()
22112 ? "\nPreferred Activities User " + user + ":"
22113 : "Preferred Activities User " + user + ":", " ",
22114 packageName, true, false)) {
22115 dumpState.setTitlePrinted(true);
22120 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
22122 FileOutputStream fout = new FileOutputStream(fd);
22123 BufferedOutputStream str = new BufferedOutputStream(fout);
22124 XmlSerializer serializer = new FastXmlSerializer();
22126 serializer.setOutput(str, StandardCharsets.UTF_8.name());
22127 serializer.startDocument(null, true);
22128 serializer.setFeature(
22129 "http://xmlpull.org/v1/doc/features.html#indent-output", true);
22130 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
22131 serializer.endDocument();
22132 serializer.flush();
22133 } catch (IllegalArgumentException e) {
22134 pw.println("Failed writing: " + e);
22135 } catch (IllegalStateException e) {
22136 pw.println("Failed writing: " + e);
22137 } catch (IOException e) {
22138 pw.println("Failed writing: " + e);
22143 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
22144 && packageName == null) {
22146 int count = mSettings.mPackages.size();
22148 pw.println("No applications!");
22151 final String prefix = " ";
22152 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
22153 if (allPackageSettings.size() == 0) {
22154 pw.println("No domain preferred apps!");
22157 pw.println("App verification status:");
22160 for (PackageSetting ps : allPackageSettings) {
22161 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
22162 if (ivi == null || ivi.getPackageName() == null) continue;
22163 pw.println(prefix + "Package: " + ivi.getPackageName());
22164 pw.println(prefix + "Domains: " + ivi.getDomainsString());
22165 pw.println(prefix + "Status: " + ivi.getStatusString());
22170 pw.println(prefix + "No app verification established.");
22173 for (int userId : sUserManager.getUserIds()) {
22174 pw.println("App linkages for user " + userId + ":");
22177 for (PackageSetting ps : allPackageSettings) {
22178 final long status = ps.getDomainVerificationStatusForUser(userId);
22179 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
22180 && !DEBUG_DOMAIN_VERIFICATION) {
22183 pw.println(prefix + "Package: " + ps.name);
22184 pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
22185 String statusStr = IntentFilterVerificationInfo.
22186 getStatusStringFromValue(status);
22187 pw.println(prefix + "Status: " + statusStr);
22192 pw.println(prefix + "No configured app linkages.");
22200 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
22201 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
22204 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
22205 mComponentResolver.dumpContentProviders(pw, dumpState, packageName);
22208 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
22209 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
22212 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
22213 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
22216 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
22217 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
22220 if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
22221 if (dumpState.onTitlePrinted()) pw.println();
22222 pw.println("Package Changes:");
22223 pw.print(" Sequence number="); pw.println(mChangedPackagesSequenceNumber);
22224 final int K = mChangedPackages.size();
22225 for (int i = 0; i < K; i++) {
22226 final SparseArray<String> changes = mChangedPackages.valueAt(i);
22227 pw.print(" User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
22228 final int N = changes.size();
22230 pw.print(" "); pw.println("No packages changed");
22232 for (int j = 0; j < N; j++) {
22233 final String pkgName = changes.valueAt(j);
22234 final int sequenceNumber = changes.keyAt(j);
22237 pw.print(sequenceNumber);
22238 pw.print(", package=");
22239 pw.println(pkgName);
22245 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
22246 // XXX should handle packageName != null by dumping only install data that
22247 // the given package is involved with.
22248 if (dumpState.onTitlePrinted()) pw.println();
22250 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
22252 ipw.println("Frozen packages:");
22253 ipw.increaseIndent();
22254 if (mFrozenPackages.size() == 0) {
22255 ipw.println("(none)");
22257 for (int i = 0; i < mFrozenPackages.size(); i++) {
22258 ipw.println(mFrozenPackages.valueAt(i));
22261 ipw.decreaseIndent();
22264 if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
22265 if (dumpState.onTitlePrinted()) pw.println();
22267 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
22269 ipw.println("Loaded volumes:");
22270 ipw.increaseIndent();
22271 if (mLoadedVolumes.size() == 0) {
22272 ipw.println("(none)");
22274 for (int i = 0; i < mLoadedVolumes.size(); i++) {
22275 ipw.println(mLoadedVolumes.valueAt(i));
22278 ipw.decreaseIndent();
22281 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
22282 && packageName == null) {
22283 mComponentResolver.dumpServicePermissions(pw, dumpState, packageName);
22286 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
22287 if (dumpState.onTitlePrinted()) pw.println();
22288 dumpDexoptStateLPr(pw, packageName);
22291 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
22292 if (dumpState.onTitlePrinted()) pw.println();
22293 dumpCompilerStatsLPr(pw, packageName);
22296 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
22297 if (dumpState.onTitlePrinted()) pw.println();
22298 mSettings.dumpReadMessagesLPr(pw, dumpState);
22301 pw.println("Package warning messages:");
22302 dumpCriticalInfo(pw, null);
22305 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
22306 dumpCriticalInfo(pw, "msg,");
22310 // PackageInstaller should be called outside of mPackages lock
22311 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
22312 // XXX should handle packageName != null by dumping only install data that
22313 // the given package is involved with.
22314 if (dumpState.onTitlePrinted()) pw.println();
22315 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120));
22318 if (!checkin && dumpState.isDumping(DumpState.DUMP_APEX)) {
22319 mApexManager.dump(pw, packageName);
22323 //TODO: b/111402650
22324 private void disableSkuSpecificApps() {
22325 String apkList[] = mContext.getResources().getStringArray(
22326 R.array.config_disableApksUnlessMatchedSku_apk_list);
22327 String skuArray[] = mContext.getResources().getStringArray(
22328 R.array.config_disableApkUnlessMatchedSku_skus_list);
22329 if (ArrayUtils.isEmpty(apkList)) {
22332 String sku = SystemProperties.get("ro.boot.hardware.sku");
22333 if (!TextUtils.isEmpty(sku) && ArrayUtils.contains(skuArray, sku)) {
22336 for (String packageName : apkList) {
22337 setSystemAppHiddenUntilInstalled(packageName, true);
22338 for (UserInfo user : sUserManager.getUsers(false)) {
22339 setSystemAppInstallState(packageName, false, user.id);
22344 private void dumpProto(FileDescriptor fd) {
22345 final ProtoOutputStream proto = new ProtoOutputStream(fd);
22347 synchronized (mPackages) {
22348 final long requiredVerifierPackageToken =
22349 proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
22350 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
22352 PackageServiceDumpProto.PackageShortProto.UID,
22354 mRequiredVerifierPackage,
22355 MATCH_DEBUG_TRIAGED_MISSING,
22356 UserHandle.USER_SYSTEM));
22357 proto.end(requiredVerifierPackageToken);
22359 if (mIntentFilterVerifierComponent != null) {
22360 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
22361 final long verifierPackageToken =
22362 proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
22363 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
22365 PackageServiceDumpProto.PackageShortProto.UID,
22367 verifierPackageName,
22368 MATCH_DEBUG_TRIAGED_MISSING,
22369 UserHandle.USER_SYSTEM));
22370 proto.end(verifierPackageToken);
22373 dumpSharedLibrariesProto(proto);
22374 dumpFeaturesProto(proto);
22375 mSettings.dumpPackagesProto(proto);
22376 mSettings.dumpSharedUsersProto(proto);
22377 dumpCriticalInfo(proto);
22382 private void dumpFeaturesProto(ProtoOutputStream proto) {
22383 synchronized (mAvailableFeatures) {
22384 final int count = mAvailableFeatures.size();
22385 for (int i = 0; i < count; i++) {
22386 mAvailableFeatures.valueAt(i).writeToProto(proto, PackageServiceDumpProto.FEATURES);
22391 private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
22392 final int count = mSharedLibraries.size();
22393 for (int i = 0; i < count; i++) {
22394 final String libName = mSharedLibraries.keyAt(i);
22395 LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(libName);
22396 if (versionedLib == null) {
22399 final int versionCount = versionedLib.size();
22400 for (int j = 0; j < versionCount; j++) {
22401 final SharedLibraryInfo libraryInfo = versionedLib.valueAt(j);
22402 final long sharedLibraryToken =
22403 proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
22404 proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libraryInfo.getName());
22405 final boolean isJar = (libraryInfo.getPath() != null);
22406 proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
22408 proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH,
22409 libraryInfo.getPath());
22411 proto.write(PackageServiceDumpProto.SharedLibraryProto.APK,
22412 libraryInfo.getPackageName());
22414 proto.end(sharedLibraryToken);
22419 @GuardedBy("mPackages")
22420 @SuppressWarnings("resource")
22421 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
22422 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
22424 ipw.println("Dexopt state:");
22425 ipw.increaseIndent();
22426 Collection<PackageParser.Package> packages;
22427 if (packageName != null) {
22428 PackageParser.Package targetPackage = mPackages.get(packageName);
22429 if (targetPackage != null) {
22430 packages = Collections.singletonList(targetPackage);
22432 ipw.println("Unable to find package: " + packageName);
22436 packages = mPackages.values();
22439 for (PackageParser.Package pkg : packages) {
22440 ipw.println("[" + pkg.packageName + "]");
22441 ipw.increaseIndent();
22442 mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
22443 mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
22444 ipw.decreaseIndent();
22448 @GuardedBy("mPackages")
22449 @SuppressWarnings("resource")
22450 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
22451 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
22453 ipw.println("Compiler stats:");
22454 ipw.increaseIndent();
22455 Collection<PackageParser.Package> packages;
22456 if (packageName != null) {
22457 PackageParser.Package targetPackage = mPackages.get(packageName);
22458 if (targetPackage != null) {
22459 packages = Collections.singletonList(targetPackage);
22461 ipw.println("Unable to find package: " + packageName);
22465 packages = mPackages.values();
22468 for (PackageParser.Package pkg : packages) {
22469 ipw.println("[" + pkg.packageName + "]");
22470 ipw.increaseIndent();
22472 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
22473 if (stats == null) {
22474 ipw.println("(No recorded stats)");
22478 ipw.decreaseIndent();
22482 private String dumpDomainString(String packageName) {
22483 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
22485 List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
22487 ArraySet<String> result = new ArraySet<>();
22488 if (iviList.size() > 0) {
22489 for (IntentFilterVerificationInfo ivi : iviList) {
22490 result.addAll(ivi.getDomains());
22493 if (filters != null && filters.size() > 0) {
22494 for (IntentFilter filter : filters) {
22495 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
22496 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
22497 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
22498 result.addAll(filter.getHostsList());
22503 StringBuilder sb = new StringBuilder(result.size() * 16);
22504 for (String domain : result) {
22505 if (sb.length() > 0) sb.append(" ");
22508 return sb.toString();
22511 // ------- apps on sdcard specific code -------
22512 static final boolean DEBUG_SD_INSTALL = false;
22514 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
22516 private static final String SD_ENCRYPTION_ALGORITHM = "AES";
22518 private boolean mMediaMounted = false;
22520 static String getEncryptKey() {
22522 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
22523 SD_ENCRYPTION_KEYSTORE_NAME);
22524 if (sdEncKey == null) {
22525 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
22526 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
22527 if (sdEncKey == null) {
22528 Slog.e(TAG, "Failed to create encryption keys");
22533 } catch (NoSuchAlgorithmException nsae) {
22534 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
22536 } catch (IOException ioe) {
22537 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
22542 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22543 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
22544 final int size = infos.size();
22545 final String[] packageNames = new String[size];
22546 final int[] packageUids = new int[size];
22547 for (int i = 0; i < size; i++) {
22548 final ApplicationInfo info = infos.get(i);
22549 packageNames[i] = info.packageName;
22550 packageUids[i] = info.uid;
22552 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
22556 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22557 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
22558 sendResourcesChangedBroadcast(mediaStatus, replacing,
22559 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
22562 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22563 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
22564 int size = pkgList.length;
22566 // Send broadcasts here
22567 Bundle extras = new Bundle();
22568 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
22569 if (uidArr != null) {
22570 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
22573 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
22575 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
22576 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
22577 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null, null);
22581 private void loadPrivatePackages(final VolumeInfo vol) {
22582 mHandler.post(() -> loadPrivatePackagesInner(vol));
22585 private void loadPrivatePackagesInner(VolumeInfo vol) {
22586 final String volumeUuid = vol.fsUuid;
22587 if (TextUtils.isEmpty(volumeUuid)) {
22588 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
22592 final ArrayList<PackageFreezer> freezers = new ArrayList<>();
22593 final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
22594 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
22596 final VersionInfo ver;
22597 final List<PackageSetting> packages;
22598 synchronized (mPackages) {
22599 ver = mSettings.findOrCreateVersion(volumeUuid);
22600 packages = mSettings.getVolumePackagesLPr(volumeUuid);
22603 for (PackageSetting ps : packages) {
22604 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
22605 synchronized (mInstallLock) {
22606 final PackageParser.Package pkg;
22608 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
22609 loaded.add(pkg.applicationInfo);
22611 } catch (PackageManagerException e) {
22612 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
22615 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
22616 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
22617 | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
22622 // Reconcile app data for all started/unlocked users
22623 final StorageManager sm = mContext.getSystemService(StorageManager.class);
22624 final UserManager um = mContext.getSystemService(UserManager.class);
22625 UserManagerInternal umInternal = getUserManagerInternal();
22626 for (UserInfo user : um.getUsers()) {
22628 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22629 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22630 } else if (umInternal.isUserRunning(user.id)) {
22631 flags = StorageManager.FLAG_STORAGE_DE;
22637 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
22638 synchronized (mInstallLock) {
22639 reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
22641 } catch (IllegalStateException e) {
22642 // Device was probably ejected, and we'll process that event momentarily
22643 Slog.w(TAG, "Failed to prepare storage: " + e);
22647 synchronized (mPackages) {
22648 final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
22650 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
22651 + mSdkVersion + "; regranting permissions for " + volumeUuid);
22653 mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated, mPackages.values(),
22654 mPermissionCallback);
22656 // Yay, everything is now upgraded
22657 ver.forceCurrent();
22659 mSettings.writeLPr();
22662 for (PackageFreezer freezer : freezers) {
22666 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
22667 sendResourcesChangedBroadcast(true, false, loaded, null);
22668 mLoadedVolumes.add(vol.getId());
22671 private void unloadPrivatePackages(final VolumeInfo vol) {
22672 mHandler.post(() -> unloadPrivatePackagesInner(vol));
22675 private void unloadPrivatePackagesInner(VolumeInfo vol) {
22676 final String volumeUuid = vol.fsUuid;
22677 if (TextUtils.isEmpty(volumeUuid)) {
22678 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
22682 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
22683 synchronized (mInstallLock) {
22684 synchronized (mPackages) {
22685 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
22686 for (PackageSetting ps : packages) {
22687 if (ps.pkg == null) continue;
22689 final ApplicationInfo info = ps.pkg.applicationInfo;
22690 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
22691 final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
22693 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
22694 "unloadPrivatePackagesInner")) {
22695 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
22697 unloaded.add(info);
22699 Slog.w(TAG, "Failed to unload " + ps.codePath);
22703 // Try very hard to release any references to this package
22704 // so we don't risk the system server being killed due to
22706 AttributeCache.instance().removePackage(ps.name);
22709 mSettings.writeLPr();
22713 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
22714 sendResourcesChangedBroadcast(false, false, unloaded, null);
22715 mLoadedVolumes.remove(vol.getId());
22717 // Try very hard to release any references to this path so we don't risk
22718 // the system server being killed due to open FDs
22719 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
22721 for (int i = 0; i < 3; i++) {
22723 System.runFinalization();
22727 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
22728 throws PackageManagerException {
22729 synchronized (mPackages) {
22730 // Normalize package name to handle renamed packages
22731 packageName = normalizePackageNameLPr(packageName);
22733 final PackageSetting ps = mSettings.mPackages.get(packageName);
22735 throw new PackageManagerException("Package " + packageName + " is unknown");
22736 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22737 throw new PackageManagerException(
22738 "Package " + packageName + " found on unknown volume " + volumeUuid
22739 + "; expected volume " + ps.volumeUuid);
22740 } else if (!ps.getInstalled(userId)) {
22741 throw new PackageManagerException(
22742 "Package " + packageName + " not installed for user " + userId);
22747 private List<String> collectAbsoluteCodePaths() {
22748 synchronized (mPackages) {
22749 List<String> codePaths = new ArrayList<>();
22750 final int packageCount = mSettings.mPackages.size();
22751 for (int i = 0; i < packageCount; i++) {
22752 final PackageSetting ps = mSettings.mPackages.valueAt(i);
22753 codePaths.add(ps.codePath.getAbsolutePath());
22760 * Examine all apps present on given mounted volume, and destroy apps that
22761 * aren't expected, either due to uninstallation or reinstallation on
22764 private void reconcileApps(String volumeUuid) {
22765 List<String> absoluteCodePaths = collectAbsoluteCodePaths();
22766 List<File> filesToDelete = null;
22768 final File[] files = FileUtils.listFilesOrEmpty(
22769 Environment.getDataAppDirectory(volumeUuid));
22770 for (File file : files) {
22771 final boolean isPackage = (isApkFile(file) || file.isDirectory())
22772 && !PackageInstallerService.isStageName(file.getName());
22774 // Ignore entries which are not packages
22778 String absolutePath = file.getAbsolutePath();
22780 boolean pathValid = false;
22781 final int absoluteCodePathCount = absoluteCodePaths.size();
22782 for (int i = 0; i < absoluteCodePathCount; i++) {
22783 String absoluteCodePath = absoluteCodePaths.get(i);
22784 if (absolutePath.startsWith(absoluteCodePath)) {
22791 if (filesToDelete == null) {
22792 filesToDelete = new ArrayList<>();
22794 filesToDelete.add(file);
22798 if (filesToDelete != null) {
22799 final int fileToDeleteCount = filesToDelete.size();
22800 for (int i = 0; i < fileToDeleteCount; i++) {
22801 File fileToDelete = filesToDelete.get(i);
22802 logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
22803 synchronized (mInstallLock) {
22804 removeCodePathLI(fileToDelete);
22811 * Reconcile all app data for the given user.
22813 * Verifies that directories exist and that ownership and labeling is
22814 * correct for all installed apps on all mounted volumes.
22816 void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
22817 final StorageManager storage = mContext.getSystemService(StorageManager.class);
22818 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
22819 final String volumeUuid = vol.getFsUuid();
22820 synchronized (mInstallLock) {
22821 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
22826 @GuardedBy("mInstallLock")
22827 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22828 boolean migrateAppData) {
22829 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
22833 * Reconcile all app data on given mounted volume.
22835 * Destroys app data that isn't expected, either due to uninstallation or
22836 * reinstallation on another volume.
22838 * Verifies that directories exist and that ownership and labeling is
22839 * correct for all installed apps.
22840 * @return list of skipped non-core packages (if {@code onlyCoreApps} is true)
22842 @GuardedBy("mInstallLock")
22843 private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22844 boolean migrateAppData, boolean onlyCoreApps) {
22845 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
22846 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
22847 List<String> result = onlyCoreApps ? new ArrayList<>() : null;
22849 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
22850 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
22852 // First look for stale data that doesn't belong, and check if things
22853 // have changed since we did our last restorecon
22854 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22855 if (StorageManager.isFileEncryptedNativeOrEmulated()
22856 && !StorageManager.isUserKeyUnlocked(userId)) {
22857 throw new RuntimeException(
22858 "Yikes, someone asked us to reconcile CE storage while " + userId
22859 + " was still locked; this would have caused massive data loss!");
22862 final File[] files = FileUtils.listFilesOrEmpty(ceDir);
22863 for (File file : files) {
22864 final String packageName = file.getName();
22866 assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22867 } catch (PackageManagerException e) {
22868 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22870 mInstaller.destroyAppData(volumeUuid, packageName, userId,
22871 StorageManager.FLAG_STORAGE_CE, 0);
22872 } catch (InstallerException e2) {
22873 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22878 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
22879 final File[] files = FileUtils.listFilesOrEmpty(deDir);
22880 for (File file : files) {
22881 final String packageName = file.getName();
22883 assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22884 } catch (PackageManagerException e) {
22885 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22887 mInstaller.destroyAppData(volumeUuid, packageName, userId,
22888 StorageManager.FLAG_STORAGE_DE, 0);
22889 } catch (InstallerException e2) {
22890 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22896 // Ensure that data directories are ready to roll for all packages
22897 // installed for this volume and user
22898 final List<PackageSetting> packages;
22899 synchronized (mPackages) {
22900 packages = mSettings.getVolumePackagesLPr(volumeUuid);
22902 int preparedCount = 0;
22903 for (PackageSetting ps : packages) {
22904 final String packageName = ps.name;
22905 if (ps.pkg == null) {
22906 Slog.w(TAG, "Odd, missing scanned package " + packageName);
22907 // TODO: might be due to legacy ASEC apps; we should circle back
22908 // and reconcile again once they're scanned
22911 // Skip non-core apps if requested
22912 if (onlyCoreApps && !ps.pkg.coreApp) {
22913 result.add(packageName);
22917 if (ps.getInstalled(userId)) {
22918 prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
22923 Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
22928 * Prepare app data for the given app just after it was installed or
22929 * upgraded. This method carefully only touches users that it's installed
22930 * for, and it forces a restorecon to handle any seinfo changes.
22932 * Verifies that directories exist and that ownership and labeling is
22933 * correct for all installed apps. If there is an ownership mismatch, it
22934 * will try recovering system apps by wiping data; third-party app data is
22937 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
22939 private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
22940 final PackageSetting ps;
22941 synchronized (mPackages) {
22942 ps = mSettings.mPackages.get(pkg.packageName);
22943 mSettings.writeKernelMappingLPr(ps);
22946 final UserManagerService um = sUserManager;
22947 UserManagerInternal umInternal = getUserManagerInternal();
22948 for (UserInfo user : um.getUsers(false /* excludeDying */)) {
22950 if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22951 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22952 } else if (umInternal.isUserRunning(user.id)) {
22953 flags = StorageManager.FLAG_STORAGE_DE;
22958 if (ps.getInstalled(user.id)) {
22959 // TODO: when user data is locked, mark that we're still dirty
22960 prepareAppDataLIF(pkg, user.id, flags);
22966 * Prepare app data for the given app.
22968 * Verifies that directories exist and that ownership and labeling is
22969 * correct for all installed apps. If there is an ownership mismatch, this
22970 * will try recovering system apps by wiping data; third-party app data is
22973 private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
22975 Slog.wtf(TAG, "Package was null!", new Throwable());
22978 prepareAppDataLeafLIF(pkg, userId, flags);
22979 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22980 for (int i = 0; i < childCount; i++) {
22981 prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
22985 private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
22986 boolean maybeMigrateAppData) {
22987 prepareAppDataLIF(pkg, userId, flags);
22989 if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
22990 // We may have just shuffled around app data directories, so
22991 // prepare them one more time
22992 prepareAppDataLIF(pkg, userId, flags);
22996 private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22997 if (DEBUG_APP_DATA) {
22998 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
22999 + Integer.toHexString(flags));
23002 final PackageSetting ps;
23003 synchronized (mPackages) {
23004 ps = mSettings.mPackages.get(pkg.packageName);
23006 final String volumeUuid = pkg.volumeUuid;
23007 final String packageName = pkg.packageName;
23009 ApplicationInfo app = (ps == null)
23010 ? pkg.applicationInfo
23011 : PackageParser.generateApplicationInfo(pkg, 0, ps.readUserState(userId), userId);
23013 app = pkg.applicationInfo;
23016 final int appId = UserHandle.getAppId(app.uid);
23018 Preconditions.checkNotNull(app.seInfo);
23020 final String seInfo = app.seInfo + (app.seInfoUser != null ? app.seInfoUser : "");
23021 long ceDataInode = -1;
23023 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
23024 appId, seInfo, app.targetSdkVersion);
23025 } catch (InstallerException e) {
23026 if (app.isSystemApp()) {
23027 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
23028 + ", but trying to recover: " + e);
23029 destroyAppDataLeafLIF(pkg, userId, flags);
23031 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
23032 appId, seInfo, app.targetSdkVersion);
23033 logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
23034 } catch (InstallerException e2) {
23035 logCriticalInfo(Log.DEBUG, "Recovery failed!");
23038 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
23041 // Prepare the application profiles only for upgrades and first boot (so that we don't
23042 // repeat the same operation at each boot).
23043 // We only have to cover the upgrade and first boot here because for app installs we
23044 // prepare the profiles before invoking dexopt (in installPackageLI).
23046 // We also have to cover non system users because we do not call the usual install package
23047 // methods for them.
23049 // NOTE: in order to speed up first boot time we only create the current profile and do not
23050 // update the content of the reference profile. A system image should already be configured
23051 // with the right profile keys and the profiles for the speed-profile prebuilds should
23052 // already be copied. That's done in #performDexOptUpgrade.
23054 // TODO(calin, mathieuc): We should use .dm files for prebuilds profiles instead of
23055 // manually copying them in #performDexOptUpgrade. When we do that we should have a more
23056 // granular check here and only update the existing profiles.
23057 if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) {
23058 mArtManagerService.prepareAppProfiles(pkg, userId,
23059 /* updateReferenceProfileContent= */ false);
23062 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
23063 // TODO: mark this structure as dirty so we persist it!
23064 synchronized (mPackages) {
23066 ps.setCeDataInode(ceDataInode, userId);
23071 prepareAppDataContentsLeafLIF(pkg, userId, flags);
23074 private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
23076 Slog.wtf(TAG, "Package was null!", new Throwable());
23079 prepareAppDataContentsLeafLIF(pkg, userId, flags);
23080 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
23081 for (int i = 0; i < childCount; i++) {
23082 prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
23086 private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
23087 final String volumeUuid = pkg.volumeUuid;
23088 final String packageName = pkg.packageName;
23089 final ApplicationInfo app = pkg.applicationInfo;
23091 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
23092 // Create a native library symlink only if we have native libraries
23093 // and if the native libraries are 32 bit libraries. We do not provide
23094 // this symlink for 64 bit libraries.
23095 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
23096 final String nativeLibPath = app.nativeLibraryDir;
23098 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
23099 nativeLibPath, userId);
23100 } catch (InstallerException e) {
23101 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
23108 * For system apps on non-FBE devices, this method migrates any existing
23109 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
23110 * requested by the app.
23112 private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
23113 if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
23114 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
23115 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
23116 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
23118 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
23120 } catch (InstallerException e) {
23121 logCriticalInfo(Log.WARN,
23122 "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
23130 public PackageFreezer freezePackage(String packageName, String killReason) {
23131 return freezePackage(packageName, UserHandle.USER_ALL, killReason);
23134 public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
23135 return new PackageFreezer(packageName, userId, killReason);
23138 public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
23139 String killReason) {
23140 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
23143 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
23144 String killReason) {
23145 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
23146 return new PackageFreezer();
23148 return freezePackage(packageName, userId, killReason);
23152 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
23153 String killReason) {
23154 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
23157 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
23158 String killReason) {
23159 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
23160 return new PackageFreezer();
23162 return freezePackage(packageName, userId, killReason);
23167 * Class that freezes and kills the given package upon creation, and
23168 * unfreezes it upon closing. This is typically used when doing surgery on
23169 * app code/data to prevent the app from running while you're working.
23171 private class PackageFreezer implements AutoCloseable {
23172 private final String mPackageName;
23173 private final PackageFreezer[] mChildren;
23175 private final boolean mWeFroze;
23177 private final AtomicBoolean mClosed = new AtomicBoolean();
23178 private final CloseGuard mCloseGuard = CloseGuard.get();
23181 * Create and return a stub freezer that doesn't actually do anything,
23182 * typically used when someone requested
23183 * {@link PackageManager#INSTALL_DONT_KILL_APP} or
23184 * {@link PackageManager#DELETE_DONT_KILL_APP}.
23186 public PackageFreezer() {
23187 mPackageName = null;
23190 mCloseGuard.open("close");
23193 public PackageFreezer(String packageName, int userId, String killReason) {
23194 synchronized (mPackages) {
23195 mPackageName = packageName;
23196 mWeFroze = mFrozenPackages.add(mPackageName);
23198 final PackageSetting ps = mSettings.mPackages.get(mPackageName);
23200 killApplication(ps.name, ps.appId, userId, killReason);
23203 final PackageParser.Package p = mPackages.get(packageName);
23204 if (p != null && p.childPackages != null) {
23205 final int N = p.childPackages.size();
23206 mChildren = new PackageFreezer[N];
23207 for (int i = 0; i < N; i++) {
23208 mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
23209 userId, killReason);
23215 mCloseGuard.open("close");
23219 protected void finalize() throws Throwable {
23221 mCloseGuard.warnIfOpen();
23229 public void close() {
23230 mCloseGuard.close();
23231 if (mClosed.compareAndSet(false, true)) {
23232 synchronized (mPackages) {
23234 mFrozenPackages.remove(mPackageName);
23237 if (mChildren != null) {
23238 for (PackageFreezer freezer : mChildren) {
23248 * Verify that given package is currently frozen.
23250 private void checkPackageFrozen(String packageName) {
23251 synchronized (mPackages) {
23252 if (!mFrozenPackages.contains(packageName)) {
23253 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
23259 public int movePackage(final String packageName, final String volumeUuid) {
23260 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23262 final int callingUid = Binder.getCallingUid();
23263 final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
23264 final int moveId = mNextMoveId.getAndIncrement();
23265 mHandler.post(() -> {
23267 movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
23268 } catch (PackageManagerException e) {
23269 Slog.w(TAG, "Failed to move " + packageName, e);
23270 mMoveCallbacks.notifyStatusChanged(moveId, e.error);
23276 private void movePackageInternal(final String packageName, final String volumeUuid,
23277 final int moveId, final int callingUid, UserHandle user)
23278 throws PackageManagerException {
23279 final StorageManager storage = mContext.getSystemService(StorageManager.class);
23280 final PackageManager pm = mContext.getPackageManager();
23282 final String currentVolumeUuid;
23283 final File codeFile;
23284 final String installerPackageName;
23285 final String packageAbiOverride;
23287 final String seinfo;
23288 final String label;
23289 final int targetSdkVersion;
23290 final PackageFreezer freezer;
23291 final int[] installedUserIds;
23292 final boolean isCurrentLocationExternal;
23295 synchronized (mPackages) {
23296 final PackageParser.Package pkg = mPackages.get(packageName);
23297 final PackageSetting ps = mSettings.mPackages.get(packageName);
23300 || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
23301 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
23303 if (pkg.applicationInfo.isSystemApp()) {
23304 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
23305 "Cannot move system application");
23308 final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
23309 final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
23310 com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
23311 if (isInternalStorage && !allow3rdPartyOnInternal) {
23312 throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
23313 "3rd party apps are not allowed on internal storage");
23316 currentVolumeUuid = ps.volumeUuid;
23318 final File probe = new File(pkg.codePath);
23319 final File probeOat = new File(probe, "oat");
23320 if (!probe.isDirectory() || !probeOat.isDirectory()) {
23321 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23322 "Move only supported for modern cluster style installs");
23325 if (Objects.equals(currentVolumeUuid, volumeUuid)) {
23326 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23327 "Package already moved to " + volumeUuid);
23329 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
23330 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
23331 "Device admin cannot be moved");
23334 if (mFrozenPackages.contains(packageName)) {
23335 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
23336 "Failed to move already frozen package");
23339 isCurrentLocationExternal = isExternal(pkg);
23340 codeFile = new File(pkg.codePath);
23341 installerPackageName = ps.installerPackageName;
23342 packageAbiOverride = ps.cpuAbiOverrideString;
23343 appId = UserHandle.getAppId(pkg.applicationInfo.uid);
23344 seinfo = pkg.applicationInfo.seInfo;
23345 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
23346 targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
23347 freezer = freezePackage(packageName, "movePackageInternal");
23348 installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
23351 final Bundle extras = new Bundle();
23352 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
23353 extras.putString(Intent.EXTRA_TITLE, label);
23354 mMoveCallbacks.notifyCreated(moveId, extras);
23357 final boolean moveCompleteApp;
23358 final File measurePath;
23360 installFlags = INSTALL_INTERNAL;
23361 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
23362 moveCompleteApp = true;
23363 measurePath = Environment.getDataAppDirectory(volumeUuid);
23364 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
23365 moveCompleteApp = false;
23366 measurePath = storage.getPrimaryPhysicalVolume().getPath();
23368 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
23369 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
23370 || !volume.isMountedWritable()) {
23372 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23373 "Move location not mounted private volume");
23376 moveCompleteApp = true;
23377 measurePath = Environment.getDataAppDirectory(volumeUuid);
23380 // If we're moving app data around, we need all the users unlocked
23381 if (moveCompleteApp) {
23382 for (int userId : installedUserIds) {
23383 if (StorageManager.isFileEncryptedNativeOrEmulated()
23384 && !StorageManager.isUserKeyUnlocked(userId)) {
23385 throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
23386 "User " + userId + " must be unlocked");
23391 final PackageStats stats = new PackageStats(null, -1);
23392 synchronized (mInstaller) {
23393 for (int userId : installedUserIds) {
23394 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
23396 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23397 "Failed to measure package size");
23402 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
23405 final long startFreeBytes = measurePath.getUsableSpace();
23406 final long sizeBytes;
23407 if (moveCompleteApp) {
23408 sizeBytes = stats.codeSize + stats.dataSize;
23410 sizeBytes = stats.codeSize;
23413 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
23415 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23416 "Not enough free space to move");
23419 mMoveCallbacks.notifyStatusChanged(moveId, 10);
23421 final CountDownLatch installedLatch = new CountDownLatch(1);
23422 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
23424 public void onUserActionRequired(Intent intent) throws RemoteException {
23425 throw new IllegalStateException();
23429 public void onPackageInstalled(String basePackageName, int returnCode, String msg,
23430 Bundle extras) throws RemoteException {
23431 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
23432 + PackageManager.installStatusToString(returnCode, msg));
23434 installedLatch.countDown();
23437 final int status = PackageManager.installStatusToPublicStatus(returnCode);
23439 case PackageInstaller.STATUS_SUCCESS:
23440 mMoveCallbacks.notifyStatusChanged(moveId,
23441 PackageManager.MOVE_SUCCEEDED);
23442 logAppMovedStorage(packageName, isCurrentLocationExternal);
23444 case PackageInstaller.STATUS_FAILURE_STORAGE:
23445 mMoveCallbacks.notifyStatusChanged(moveId,
23446 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
23449 mMoveCallbacks.notifyStatusChanged(moveId,
23450 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
23456 final MoveInfo move;
23457 if (moveCompleteApp) {
23458 // Kick off a thread to report progress estimates
23462 if (installedLatch.await(1, TimeUnit.SECONDS)) {
23465 } catch (InterruptedException ignored) {
23468 final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
23469 final int progress = 10 + (int) MathUtils.constrain(
23470 ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
23471 mMoveCallbacks.notifyStatusChanged(moveId, progress);
23475 final String dataAppName = codeFile.getName();
23476 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
23477 dataAppName, appId, seinfo, targetSdkVersion);
23482 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
23484 final Message msg = mHandler.obtainMessage(INIT_COPY);
23485 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
23486 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
23487 installerPackageName, volumeUuid, null /*verificationInfo*/, user,
23488 packageAbiOverride, null /*grantedPermissions*/,
23489 null /*whitelistedRestrictedPermissions*/, PackageParser.SigningDetails.UNKNOWN,
23490 PackageManager.INSTALL_REASON_UNKNOWN, PackageManager.VERSION_CODE_HIGHEST);
23491 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
23494 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
23495 System.identityHashCode(msg.obj));
23496 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
23497 System.identityHashCode(msg.obj));
23499 mHandler.sendMessage(msg);
23503 * Logs that an app has been moved from internal to external storage and vice versa.
23504 * @param packageName The package that was moved.
23506 private void logAppMovedStorage(String packageName, boolean isPreviousLocationExternal) {
23507 final PackageParser.Package pkg;
23508 synchronized (mPackages) {
23509 pkg = mPackages.get(packageName);
23515 final StorageManager storage = mContext.getSystemService(StorageManager.class);
23516 VolumeInfo volume = storage.findVolumeByUuid(pkg.applicationInfo.storageUuid.toString());
23517 int packageExternalStorageType = getPackageExternalStorageType(volume, isExternal(pkg));
23519 if (!isPreviousLocationExternal && isExternal(pkg)) {
23520 // Move from internal to external storage.
23521 StatsLog.write(StatsLog.APP_MOVED_STORAGE_REPORTED, packageExternalStorageType,
23522 StatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_EXTERNAL,
23524 } else if (isPreviousLocationExternal && !isExternal(pkg)) {
23525 // Move from external to internal storage.
23526 StatsLog.write(StatsLog.APP_MOVED_STORAGE_REPORTED, packageExternalStorageType,
23527 StatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_INTERNAL,
23533 public int movePrimaryStorage(String volumeUuid) throws RemoteException {
23534 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23536 final int realMoveId = mNextMoveId.getAndIncrement();
23537 final Bundle extras = new Bundle();
23538 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
23539 mMoveCallbacks.notifyCreated(realMoveId, extras);
23541 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
23543 public void onCreated(int moveId, Bundle extras) {
23548 public void onStatusChanged(int moveId, int status, long estMillis) {
23549 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
23553 final StorageManager storage = mContext.getSystemService(StorageManager.class);
23554 storage.setPrimaryStorageUuid(volumeUuid, callback);
23559 public int getMoveStatus(int moveId) {
23560 mContext.enforceCallingOrSelfPermission(
23561 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23562 return mMoveCallbacks.mLastStatus.get(moveId);
23566 public void registerMoveCallback(IPackageMoveObserver callback) {
23567 mContext.enforceCallingOrSelfPermission(
23568 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23569 mMoveCallbacks.register(callback);
23573 public void unregisterMoveCallback(IPackageMoveObserver callback) {
23574 mContext.enforceCallingOrSelfPermission(
23575 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23576 mMoveCallbacks.unregister(callback);
23580 public boolean setInstallLocation(int loc) {
23581 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
23583 if (getInstallLocation() == loc) {
23586 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
23587 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
23588 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
23589 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
23596 public int getInstallLocation() {
23597 // allow instant app access
23598 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
23599 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
23600 PackageHelper.APP_INSTALL_AUTO);
23603 /** Called by UserManagerService */
23604 void cleanUpUser(UserManagerService userManager, int userHandle) {
23605 synchronized (mPackages) {
23606 mDirtyUsers.remove(userHandle);
23607 mUserNeedsBadging.delete(userHandle);
23608 mSettings.removeUserLPw(userHandle);
23609 mPendingBroadcasts.remove(userHandle);
23610 mInstantAppRegistry.onUserRemovedLPw(userHandle);
23611 removeUnusedPackagesLPw(userManager, userHandle);
23616 * We're removing userHandle and would like to remove any downloaded packages
23617 * that are no longer in use by any other user.
23618 * @param userHandle the user being removed
23620 @GuardedBy("mPackages")
23621 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
23622 final boolean DEBUG_CLEAN_APKS = false;
23623 int [] users = userManager.getUserIds();
23624 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
23625 while (psit.hasNext()) {
23626 PackageSetting ps = psit.next();
23627 if (ps.pkg == null) {
23630 final String packageName = ps.pkg.packageName;
23631 // Skip over if system app or static shared library
23632 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0
23633 || !TextUtils.isEmpty(ps.pkg.staticSharedLibName)) {
23636 if (DEBUG_CLEAN_APKS) {
23637 Slog.i(TAG, "Checking package " + packageName);
23639 boolean keep = shouldKeepUninstalledPackageLPr(packageName);
23641 if (DEBUG_CLEAN_APKS) {
23642 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO");
23645 for (int i = 0; i < users.length; i++) {
23646 if (users[i] != userHandle && ps.getInstalled(users[i])) {
23648 if (DEBUG_CLEAN_APKS) {
23649 Slog.i(TAG, " Keeping package " + packageName + " for user "
23657 if (DEBUG_CLEAN_APKS) {
23658 Slog.i(TAG, " Removing package " + packageName);
23661 mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23667 /** Called by UserManagerService */
23668 void createNewUser(int userId, String[] disallowedPackages) {
23669 synchronized (mInstallLock) {
23670 mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
23672 synchronized (mPackages) {
23673 scheduleWritePackageRestrictionsLocked(userId);
23674 scheduleWritePackageListLocked(userId);
23675 primeDomainVerificationsLPw(userId);
23679 void onNewUserCreated(final int userId) {
23680 mDefaultPermissionPolicy.grantDefaultPermissions(userId);
23681 synchronized(mPackages) {
23682 // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
23683 mPermissionManager.updateAllPermissions(
23684 StorageManager.UUID_PRIVATE_INTERNAL, true, mPackages.values(),
23685 mPermissionCallback);
23690 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
23691 mContext.enforceCallingOrSelfPermission(
23692 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
23693 "Only package verification agents can read the verifier device identity");
23695 synchronized (mPackages) {
23696 return mSettings.getVerifierDeviceIdentityLPw();
23701 public void setPermissionEnforced(String permission, boolean enforced) {
23702 // TODO: Now that we no longer change GID for storage, this should to away.
23703 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
23704 "setPermissionEnforced");
23705 if (READ_EXTERNAL_STORAGE.equals(permission)) {
23706 synchronized (mPackages) {
23707 if (mSettings.mReadExternalStorageEnforced == null
23708 || mSettings.mReadExternalStorageEnforced != enforced) {
23709 mSettings.mReadExternalStorageEnforced =
23710 enforced ? Boolean.TRUE : Boolean.FALSE;
23711 mSettings.writeLPr();
23714 // kill any non-foreground processes so we restart them and
23715 // grant/revoke the GID.
23716 final IActivityManager am = ActivityManager.getService();
23718 final long token = Binder.clearCallingIdentity();
23720 am.killProcessesBelowForeground("setPermissionEnforcement");
23721 } catch (RemoteException e) {
23723 Binder.restoreCallingIdentity(token);
23727 throw new IllegalArgumentException("No selective enforcement for " + permission);
23733 public boolean isPermissionEnforced(String permission) {
23734 // allow instant applications
23739 public boolean isStorageLow() {
23740 // allow instant applications
23741 final long token = Binder.clearCallingIdentity();
23743 final DeviceStorageMonitorInternal
23744 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
23746 return dsm.isMemoryLow();
23751 Binder.restoreCallingIdentity(token);
23756 public IPackageInstaller getPackageInstaller() {
23757 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23760 return mInstallerService;
23764 public IArtManager getArtManager() {
23765 return mArtManagerService;
23768 private boolean userNeedsBadging(int userId) {
23769 int index = mUserNeedsBadging.indexOfKey(userId);
23771 final UserInfo userInfo;
23772 final long token = Binder.clearCallingIdentity();
23774 userInfo = sUserManager.getUserInfo(userId);
23776 Binder.restoreCallingIdentity(token);
23779 if (userInfo != null && userInfo.isManagedProfile()) {
23784 mUserNeedsBadging.put(userId, b);
23787 return mUserNeedsBadging.valueAt(index);
23791 public KeySet getKeySetByAlias(String packageName, String alias) {
23792 if (packageName == null || alias == null) {
23795 synchronized(mPackages) {
23796 final PackageParser.Package pkg = mPackages.get(packageName);
23798 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23799 throw new IllegalArgumentException("Unknown package: " + packageName);
23801 final PackageSetting ps = (PackageSetting) pkg.mExtras;
23802 if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
23803 Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
23804 throw new IllegalArgumentException("Unknown package: " + packageName);
23806 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23807 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
23812 public KeySet getSigningKeySet(String packageName) {
23813 if (packageName == null) {
23816 synchronized(mPackages) {
23817 final int callingUid = Binder.getCallingUid();
23818 final int callingUserId = UserHandle.getUserId(callingUid);
23819 final PackageParser.Package pkg = mPackages.get(packageName);
23821 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23822 throw new IllegalArgumentException("Unknown package: " + packageName);
23824 final PackageSetting ps = (PackageSetting) pkg.mExtras;
23825 if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
23826 // filter and pretend the package doesn't exist
23827 Slog.w(TAG, "KeySet requested for filtered package: " + packageName
23828 + ", uid:" + callingUid);
23829 throw new IllegalArgumentException("Unknown package: " + packageName);
23831 if (pkg.applicationInfo.uid != callingUid
23832 && Process.SYSTEM_UID != callingUid) {
23833 throw new SecurityException("May not access signing KeySet of other apps.");
23835 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23836 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
23841 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
23842 final int callingUid = Binder.getCallingUid();
23843 if (getInstantAppPackageName(callingUid) != null) {
23846 if (packageName == null || ks == null) {
23849 synchronized(mPackages) {
23850 final PackageParser.Package pkg = mPackages.get(packageName);
23852 || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
23853 UserHandle.getUserId(callingUid))) {
23854 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23855 throw new IllegalArgumentException("Unknown package: " + packageName);
23857 IBinder ksh = ks.getToken();
23858 if (ksh instanceof KeySetHandle) {
23859 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23860 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
23867 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
23868 final int callingUid = Binder.getCallingUid();
23869 if (getInstantAppPackageName(callingUid) != null) {
23872 if (packageName == null || ks == null) {
23875 synchronized(mPackages) {
23876 final PackageParser.Package pkg = mPackages.get(packageName);
23878 || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
23879 UserHandle.getUserId(callingUid))) {
23880 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23881 throw new IllegalArgumentException("Unknown package: " + packageName);
23883 IBinder ksh = ks.getToken();
23884 if (ksh instanceof KeySetHandle) {
23885 final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23886 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
23892 @GuardedBy("mPackages")
23893 private void deletePackageIfUnusedLPr(final String packageName) {
23894 PackageSetting ps = mSettings.mPackages.get(packageName);
23898 if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
23899 // TODO Implement atomic delete if package is unused
23900 // It is currently possible that the package will be deleted even if it is installed
23901 // after this method returns.
23902 mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23903 0, PackageManager.DELETE_ALL_USERS));
23908 * Check and throw if the given before/after packages would be considered a
23911 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
23912 throws PackageManagerException {
23913 if (after.getLongVersionCode() < before.getLongVersionCode()) {
23914 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23915 "Update version code " + after.versionCode + " is older than current "
23916 + before.getLongVersionCode());
23917 } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
23918 if (after.baseRevisionCode < before.baseRevisionCode) {
23919 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23920 "Update base revision code " + after.baseRevisionCode
23921 + " is older than current " + before.baseRevisionCode);
23924 if (!ArrayUtils.isEmpty(after.splitNames)) {
23925 for (int i = 0; i < after.splitNames.length; i++) {
23926 final String splitName = after.splitNames[i];
23927 final int j = ArrayUtils.indexOf(before.splitNames, splitName);
23929 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
23930 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23931 "Update split " + splitName + " revision code "
23932 + after.splitRevisionCodes[i] + " is older than current "
23933 + before.splitRevisionCodes[j]);
23941 private static class MoveCallbacks extends Handler {
23942 private static final int MSG_CREATED = 1;
23943 private static final int MSG_STATUS_CHANGED = 2;
23945 private final RemoteCallbackList<IPackageMoveObserver>
23946 mCallbacks = new RemoteCallbackList<>();
23948 private final SparseIntArray mLastStatus = new SparseIntArray();
23950 public MoveCallbacks(Looper looper) {
23954 public void register(IPackageMoveObserver callback) {
23955 mCallbacks.register(callback);
23958 public void unregister(IPackageMoveObserver callback) {
23959 mCallbacks.unregister(callback);
23963 public void handleMessage(Message msg) {
23964 final SomeArgs args = (SomeArgs) msg.obj;
23965 final int n = mCallbacks.beginBroadcast();
23966 for (int i = 0; i < n; i++) {
23967 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
23969 invokeCallback(callback, msg.what, args);
23970 } catch (RemoteException ignored) {
23973 mCallbacks.finishBroadcast();
23977 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
23978 throws RemoteException {
23980 case MSG_CREATED: {
23981 callback.onCreated(args.argi1, (Bundle) args.arg2);
23984 case MSG_STATUS_CHANGED: {
23985 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
23991 private void notifyCreated(int moveId, Bundle extras) {
23992 Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
23994 final SomeArgs args = SomeArgs.obtain();
23995 args.argi1 = moveId;
23996 args.arg2 = extras;
23997 obtainMessage(MSG_CREATED, args).sendToTarget();
24000 private void notifyStatusChanged(int moveId, int status) {
24001 notifyStatusChanged(moveId, status, -1);
24004 private void notifyStatusChanged(int moveId, int status, long estMillis) {
24005 Slog.v(TAG, "Move " + moveId + " status " + status);
24007 final SomeArgs args = SomeArgs.obtain();
24008 args.argi1 = moveId;
24009 args.argi2 = status;
24010 args.arg3 = estMillis;
24011 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
24013 synchronized (mLastStatus) {
24014 mLastStatus.put(moveId, status);
24019 private final static class OnPermissionChangeListeners extends Handler {
24020 private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
24022 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
24023 new RemoteCallbackList<>();
24025 public OnPermissionChangeListeners(Looper looper) {
24030 public void handleMessage(Message msg) {
24031 switch (msg.what) {
24032 case MSG_ON_PERMISSIONS_CHANGED: {
24033 final int uid = msg.arg1;
24034 handleOnPermissionsChanged(uid);
24039 public void addListenerLocked(IOnPermissionsChangeListener listener) {
24040 mPermissionListeners.register(listener);
24044 public void removeListenerLocked(IOnPermissionsChangeListener listener) {
24045 mPermissionListeners.unregister(listener);
24048 public void onPermissionsChanged(int uid) {
24049 if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
24050 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
24054 private void handleOnPermissionsChanged(int uid) {
24055 final int count = mPermissionListeners.beginBroadcast();
24057 for (int i = 0; i < count; i++) {
24058 IOnPermissionsChangeListener callback = mPermissionListeners
24059 .getBroadcastItem(i);
24061 callback.onPermissionsChanged(uid);
24062 } catch (RemoteException e) {
24063 Log.e(TAG, "Permission listener is dead", e);
24067 mPermissionListeners.finishBroadcast();
24072 private class PackageManagerNative extends IPackageManagerNative.Stub {
24074 public String[] getNamesForUids(int[] uids) throws RemoteException {
24075 final String[] results = PackageManagerService.this.getNamesForUids(uids);
24076 // massage results so they can be parsed by the native binder
24077 for (int i = results.length - 1; i >= 0; --i) {
24078 if (results[i] == null) {
24085 // NB: this differentiates between preloads and sideloads
24087 public String getInstallerForPackage(String packageName) throws RemoteException {
24088 final String installerName = getInstallerPackageName(packageName);
24089 if (!TextUtils.isEmpty(installerName)) {
24090 return installerName;
24092 // differentiate between preload and sideload
24093 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
24094 ApplicationInfo appInfo = getApplicationInfo(packageName,
24096 /*userId*/ callingUser);
24097 if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
24104 public long getVersionCodeForPackage(String packageName) throws RemoteException {
24106 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
24107 PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
24108 if (pInfo != null) {
24109 return pInfo.getLongVersionCode();
24111 } catch (Exception e) {
24117 public int getTargetSdkVersionForPackage(String packageName)
24118 throws RemoteException {
24119 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
24120 ApplicationInfo info = getApplicationInfo(packageName, 0, callingUser);
24121 if (info == null) {
24122 throw new RemoteException(
24123 "Couldn't get ApplicationInfo for package " + packageName);
24125 return info.targetSdkVersion;
24129 public boolean[] isAudioPlaybackCaptureAllowed(String[] packageNames)
24130 throws RemoteException {
24131 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
24132 boolean[] results = new boolean[packageNames.length];
24133 for (int i = results.length - 1; i >= 0; --i) {
24134 ApplicationInfo appInfo = getApplicationInfo(packageNames[i], 0, callingUser);
24135 results[i] = appInfo == null ? false : appInfo.isAudioPlaybackCaptureAllowed();
24141 public int getLocationFlags(String packageName) throws RemoteException {
24142 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
24143 ApplicationInfo appInfo = getApplicationInfo(packageName,
24145 /*userId*/ callingUser);
24146 if (appInfo == null) {
24147 throw new RemoteException(
24148 "Couldn't get ApplicationInfo for package " + packageName);
24150 return ((appInfo.isSystemApp() ? IPackageManagerNative.LOCATION_SYSTEM : 0)
24151 | (appInfo.isVendor() ? IPackageManagerNative.LOCATION_VENDOR : 0)
24152 | (appInfo.isProduct() ? IPackageManagerNative.LOCATION_PRODUCT : 0));
24156 public String getModuleMetadataPackageName() throws RemoteException {
24157 return PackageManagerService.this.mModuleInfoProvider.getPackageName();
24161 private class PackageManagerInternalImpl extends PackageManagerInternal {
24163 public void updatePermissionFlagsTEMP(String permName, String packageName, int flagMask,
24164 int flagValues, int userId) {
24165 PackageManagerService.this.updatePermissionFlags(
24166 permName, packageName, flagMask, flagValues, true, userId);
24170 public List<ApplicationInfo> getInstalledApplications(int flags, int userId,
24172 return PackageManagerService.this.getInstalledApplicationsListInternal(flags, userId,
24178 public boolean isPlatformSigned(String packageName) {
24179 PackageSetting packageSetting = mSettings.mPackages.get(packageName);
24180 if (packageSetting == null) {
24183 PackageParser.Package pkg = packageSetting.pkg;
24185 // May happen if package in on a removable sd card
24188 return pkg.mSigningDetails.hasAncestorOrSelf(mPlatformPackage.mSigningDetails)
24189 || mPlatformPackage.mSigningDetails.checkCapability(pkg.mSigningDetails,
24190 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
24194 public boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName) {
24195 SigningDetails sd = getSigningDetails(packageName);
24199 return sd.hasSha256Certificate(restoringFromSigHash,
24200 SigningDetails.CertCapabilities.INSTALLED_DATA);
24204 public boolean isDataRestoreSafe(Signature restoringFromSig, String packageName) {
24205 SigningDetails sd = getSigningDetails(packageName);
24209 return sd.hasCertificate(restoringFromSig,
24210 SigningDetails.CertCapabilities.INSTALLED_DATA);
24214 public boolean hasSignatureCapability(int serverUid, int clientUid,
24215 @SigningDetails.CertCapabilities int capability) {
24216 SigningDetails serverSigningDetails = getSigningDetails(serverUid);
24217 SigningDetails clientSigningDetails = getSigningDetails(clientUid);
24218 return serverSigningDetails.checkCapability(clientSigningDetails, capability)
24219 || clientSigningDetails.hasAncestorOrSelf(serverSigningDetails);
24223 private SigningDetails getSigningDetails(@NonNull String packageName) {
24224 synchronized (mPackages) {
24225 PackageParser.Package p = mPackages.get(packageName);
24229 return p.mSigningDetails;
24233 private SigningDetails getSigningDetails(int uid) {
24234 synchronized (mPackages) {
24235 final int appId = UserHandle.getAppId(uid);
24236 final Object obj = mSettings.getSettingLPr(appId);
24238 if (obj instanceof SharedUserSetting) {
24239 return ((SharedUserSetting) obj).signatures.mSigningDetails;
24240 } else if (obj instanceof PackageSetting) {
24241 final PackageSetting ps = (PackageSetting) obj;
24242 return ps.signatures.mSigningDetails;
24245 return SigningDetails.UNKNOWN;
24250 public int getPermissionFlagsTEMP(String permName, String packageName, int userId) {
24251 return PackageManagerService.this.getPermissionFlags(permName, packageName, userId);
24255 public boolean isInstantApp(String packageName, int userId) {
24256 return PackageManagerService.this.isInstantApp(packageName, userId);
24260 public String getInstantAppPackageName(int uid) {
24261 return PackageManagerService.this.getInstantAppPackageName(uid);
24265 public boolean filterAppAccess(PackageParser.Package pkg, int callingUid, int userId) {
24266 synchronized (mPackages) {
24267 return PackageManagerService.this.filterAppAccessLPr(
24268 (PackageSetting) pkg.mExtras, callingUid, userId);
24273 public PackageParser.Package getPackage(String packageName) {
24274 synchronized (mPackages) {
24275 packageName = resolveInternalPackageNameLPr(
24276 packageName, PackageManager.VERSION_CODE_HIGHEST);
24277 return mPackages.get(packageName);
24282 public PackageList getPackageList(PackageListObserver observer) {
24283 synchronized (mPackages) {
24284 final int N = mPackages.size();
24285 final ArrayList<String> list = new ArrayList<>(N);
24286 for (int i = 0; i < N; i++) {
24287 list.add(mPackages.keyAt(i));
24289 final PackageList packageList = new PackageList(list, observer);
24290 if (observer != null) {
24291 mPackageListObservers.add(packageList);
24293 return packageList;
24298 public void removePackageListObserver(PackageListObserver observer) {
24299 synchronized (mPackages) {
24300 mPackageListObservers.remove(observer);
24305 public PackageParser.Package getDisabledSystemPackage(String packageName) {
24306 synchronized (mPackages) {
24307 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
24308 return (ps != null) ? ps.pkg : null;
24313 public @Nullable String getDisabledSystemPackageName(@NonNull String packageName) {
24314 PackageParser.Package pkg = getDisabledSystemPackage(packageName);
24315 return pkg == null ? null : pkg.packageName;
24319 public String getKnownPackageName(int knownPackage, int userId) {
24320 switch(knownPackage) {
24321 case PackageManagerInternal.PACKAGE_BROWSER:
24322 return getDefaultBrowserPackageName(userId);
24323 case PackageManagerInternal.PACKAGE_INSTALLER:
24324 return mRequiredInstallerPackage;
24325 case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
24326 return mSetupWizardPackage;
24327 case PackageManagerInternal.PACKAGE_SYSTEM:
24329 case PackageManagerInternal.PACKAGE_VERIFIER:
24330 return mRequiredVerifierPackage;
24331 case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER:
24332 return mSystemTextClassifierPackage;
24333 case PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER:
24334 return mRequiredPermissionControllerPackage;
24335 case PackageManagerInternal.PACKAGE_WELLBEING:
24336 return mWellbeingPackage;
24337 case PackageManagerInternal.PACKAGE_DOCUMENTER:
24338 return mDocumenterPackage;
24339 case PackageManagerInternal.PACKAGE_CONFIGURATOR:
24340 return mConfiguratorPackage;
24341 case PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER:
24342 return mIncidentReportApproverPackage;
24343 case PackageManagerInternal.PACKAGE_APP_PREDICTOR:
24344 return mAppPredictionServicePackage;
24350 public boolean isResolveActivityComponent(ComponentInfo component) {
24351 return mResolveActivity.packageName.equals(component.packageName)
24352 && mResolveActivity.name.equals(component.name);
24356 public void setLocationPackagesProvider(PackagesProvider provider) {
24357 mDefaultPermissionPolicy.setLocationPackagesProvider(provider);
24361 public void setLocationExtraPackagesProvider(PackagesProvider provider) {
24362 mDefaultPermissionPolicy.setLocationExtraPackagesProvider(provider);
24366 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
24367 mDefaultPermissionPolicy.setVoiceInteractionPackagesProvider(provider);
24371 public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
24372 mDefaultPermissionPolicy.setUseOpenWifiAppPackagesProvider(provider);
24376 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
24377 mDefaultPermissionPolicy.setSyncAdapterPackagesProvider(provider);
24381 public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
24382 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultUseOpenWifiApp(
24383 packageName, userId);
24387 public void setKeepUninstalledPackages(final List<String> packageList) {
24388 Preconditions.checkNotNull(packageList);
24389 List<String> removedFromList = null;
24390 synchronized (mPackages) {
24391 if (mKeepUninstalledPackages != null) {
24392 final int packagesCount = mKeepUninstalledPackages.size();
24393 for (int i = 0; i < packagesCount; i++) {
24394 String oldPackage = mKeepUninstalledPackages.get(i);
24395 if (packageList != null && packageList.contains(oldPackage)) {
24398 if (removedFromList == null) {
24399 removedFromList = new ArrayList<>();
24401 removedFromList.add(oldPackage);
24404 mKeepUninstalledPackages = new ArrayList<>(packageList);
24405 if (removedFromList != null) {
24406 final int removedCount = removedFromList.size();
24407 for (int i = 0; i < removedCount; i++) {
24408 deletePackageIfUnusedLPr(removedFromList.get(i));
24415 public boolean isPermissionsReviewRequired(String packageName, int userId) {
24416 synchronized (mPackages) {
24417 final PackageParser.Package pkg = mPackages.get(packageName);
24422 return mPermissionManager.isPermissionsReviewRequired(pkg, userId);
24427 public PackageInfo getPackageInfo(
24428 String packageName, int flags, int filterCallingUid, int userId) {
24429 return PackageManagerService.this
24430 .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
24431 flags, filterCallingUid, userId);
24435 public Bundle getSuspendedPackageLauncherExtras(String packageName, int userId) {
24436 synchronized (mPackages) {
24437 final PackageSetting ps = mSettings.mPackages.get(packageName);
24438 PersistableBundle launcherExtras = null;
24440 launcherExtras = ps.readUserState(userId).suspendedLauncherExtras;
24442 return (launcherExtras != null) ? new Bundle(launcherExtras.deepCopy()) : null;
24447 public boolean isPackageSuspended(String packageName, int userId) {
24448 synchronized (mPackages) {
24449 final PackageSetting ps = mSettings.mPackages.get(packageName);
24450 return (ps != null) ? ps.getSuspended(userId) : false;
24455 public String getSuspendingPackage(String suspendedPackage, int userId) {
24456 synchronized (mPackages) {
24457 final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
24458 return (ps != null) ? ps.readUserState(userId).suspendingPackage : null;
24463 public SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage, int userId) {
24464 synchronized (mPackages) {
24465 final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
24466 return (ps != null) ? ps.readUserState(userId).dialogInfo : null;
24471 public int getDistractingPackageRestrictions(String packageName, int userId) {
24472 synchronized (mPackages) {
24473 final PackageSetting ps = mSettings.mPackages.get(packageName);
24474 return (ps != null) ? ps.getDistractionFlags(userId) : RESTRICTION_NONE;
24479 public int getPackageUid(String packageName, int flags, int userId) {
24480 return PackageManagerService.this
24481 .getPackageUid(packageName, flags, userId);
24485 public ApplicationInfo getApplicationInfo(
24486 String packageName, int flags, int filterCallingUid, int userId) {
24487 return PackageManagerService.this
24488 .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
24492 public ActivityInfo getActivityInfo(
24493 ComponentName component, int flags, int filterCallingUid, int userId) {
24494 return PackageManagerService.this
24495 .getActivityInfoInternal(component, flags, filterCallingUid, userId);
24499 public List<ResolveInfo> queryIntentActivities(
24500 Intent intent, int flags, int filterCallingUid, int userId) {
24501 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
24502 return PackageManagerService.this
24503 .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
24504 userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
24508 public List<ResolveInfo> queryIntentServices(
24509 Intent intent, int flags, int callingUid, int userId) {
24510 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
24511 return PackageManagerService.this
24512 .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
24517 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
24519 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
24523 public ComponentName getDefaultHomeActivity(int userId) {
24524 return PackageManagerService.this.getDefaultHomeActivity(userId);
24528 public void setDeviceAndProfileOwnerPackages(
24529 int deviceOwnerUserId, String deviceOwnerPackage,
24530 SparseArray<String> profileOwnerPackages) {
24531 mProtectedPackages.setDeviceAndProfileOwnerPackages(
24532 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
24534 final ArraySet<Integer> usersWithPoOrDo = new ArraySet<>();
24535 if (deviceOwnerPackage != null) {
24536 usersWithPoOrDo.add(deviceOwnerUserId);
24538 final int sz = profileOwnerPackages.size();
24539 for (int i = 0; i < sz; i++) {
24540 if (profileOwnerPackages.valueAt(i) != null) {
24541 usersWithPoOrDo.add(profileOwnerPackages.keyAt(i));
24544 unsuspendForNonSystemSuspendingPackages(usersWithPoOrDo);
24548 public boolean isPackageDataProtected(int userId, String packageName) {
24549 return mProtectedPackages.isPackageDataProtected(userId, packageName);
24553 public boolean isPackageStateProtected(String packageName, int userId) {
24554 return mProtectedPackages.isPackageStateProtected(userId, packageName);
24558 public boolean isPackageEphemeral(int userId, String packageName) {
24559 synchronized (mPackages) {
24560 final PackageSetting ps = mSettings.mPackages.get(packageName);
24561 return ps != null ? ps.getInstantApp(userId) : false;
24566 public boolean wasPackageEverLaunched(String packageName, int userId) {
24567 synchronized (mPackages) {
24568 return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
24573 public boolean isEnabledAndMatches(ComponentInfo info, int flags, int userId) {
24574 synchronized (mPackages) {
24575 return mSettings.isEnabledAndMatchLPr(info, flags, userId);
24580 public boolean userNeedsBadging(int userId) {
24581 synchronized (mPackages) {
24582 return PackageManagerService.this.userNeedsBadging(userId);
24587 public void grantRuntimePermission(String packageName, String permName, int userId,
24588 boolean overridePolicy) {
24589 PackageManagerService.this.mPermissionManager.grantRuntimePermission(
24590 permName, packageName, overridePolicy, getCallingUid(), userId,
24591 mPermissionCallback);
24595 public void revokeRuntimePermission(String packageName, String permName, int userId,
24596 boolean overridePolicy) {
24597 mPermissionManager.revokeRuntimePermission(
24598 permName, packageName, overridePolicy, userId,
24599 mPermissionCallback);
24603 public String getNameForUid(int uid) {
24604 return PackageManagerService.this.getNameForUid(uid);
24608 public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
24609 Intent origIntent, String resolvedType, String callingPackage,
24610 Bundle verificationBundle, int userId) {
24611 PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
24612 responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
24617 public void grantEphemeralAccess(int userId, Intent intent,
24618 int targetAppId, int ephemeralAppId) {
24619 synchronized (mPackages) {
24620 mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
24621 targetAppId, ephemeralAppId);
24626 public boolean isInstantAppInstallerComponent(ComponentName component) {
24627 synchronized (mPackages) {
24628 return mInstantAppInstallerActivity != null
24629 && mInstantAppInstallerActivity.getComponentName().equals(component);
24634 public void pruneInstantApps() {
24635 mInstantAppRegistry.pruneInstantApps();
24639 public String getSetupWizardPackageName() {
24640 return mSetupWizardPackage;
24643 public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
24644 if (policy != null) {
24645 mExternalSourcesPolicy = policy;
24650 public boolean isPackagePersistent(String packageName) {
24651 synchronized (mPackages) {
24652 PackageParser.Package pkg = mPackages.get(packageName);
24654 ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
24655 | ApplicationInfo.FLAG_PERSISTENT)) ==
24656 (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
24662 public boolean isLegacySystemApp(PackageParser.Package pkg) {
24663 synchronized (mPackages) {
24664 final PackageSetting ps = (PackageSetting) pkg.mExtras;
24665 return mPromoteSystemApps
24667 && mExistingSystemPackages.contains(ps.name);
24672 public List<PackageInfo> getOverlayPackages(int userId) {
24673 final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
24674 synchronized (mPackages) {
24675 for (PackageParser.Package p : mPackages.values()) {
24676 if (p.mOverlayTarget != null) {
24677 PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
24679 overlayPackages.add(pkg);
24684 return overlayPackages;
24688 public List<String> getTargetPackageNames(int userId) {
24689 List<String> targetPackages = new ArrayList<>();
24690 synchronized (mPackages) {
24691 for (PackageParser.Package p : mPackages.values()) {
24692 if (p.mOverlayTarget == null) {
24693 targetPackages.add(p.packageName);
24697 return targetPackages;
24701 public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
24702 @Nullable List<String> overlayPackageNames) {
24703 synchronized (mPackages) {
24704 if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
24705 Slog.e(TAG, "failed to find package " + targetPackageName);
24708 ArrayList<String> overlayPaths = null;
24709 if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
24710 final int N = overlayPackageNames.size();
24711 overlayPaths = new ArrayList<>(N);
24712 for (int i = 0; i < N; i++) {
24713 final String packageName = overlayPackageNames.get(i);
24714 final PackageParser.Package pkg = mPackages.get(packageName);
24716 Slog.e(TAG, "failed to find package " + packageName);
24719 overlayPaths.add(pkg.baseCodePath);
24723 final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
24724 ps.setOverlayPaths(overlayPaths, userId);
24730 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
24731 int flags, int userId, boolean resolveForStart, int filterCallingUid) {
24732 return resolveIntentInternal(
24733 intent, resolvedType, flags, userId, resolveForStart, filterCallingUid);
24737 public ResolveInfo resolveService(Intent intent, String resolvedType,
24738 int flags, int userId, int callingUid) {
24739 return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
24743 public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
24744 return PackageManagerService.this.resolveContentProviderInternal(
24745 name, flags, userId);
24749 public void addIsolatedUid(int isolatedUid, int ownerUid) {
24750 synchronized (mPackages) {
24751 mIsolatedOwners.put(isolatedUid, ownerUid);
24756 public void removeIsolatedUid(int isolatedUid) {
24757 synchronized (mPackages) {
24758 mIsolatedOwners.delete(isolatedUid);
24763 public int getUidTargetSdkVersion(int uid) {
24764 synchronized (mPackages) {
24765 return getUidTargetSdkVersionLockedLPr(uid);
24770 public int getPackageTargetSdkVersion(String packageName) {
24771 synchronized (mPackages) {
24772 return getPackageTargetSdkVersionLockedLPr(packageName);
24777 public boolean canAccessInstantApps(int callingUid, int userId) {
24778 return PackageManagerService.this.canViewInstantApps(callingUid, userId);
24782 public boolean canAccessComponent(int callingUid, ComponentName component, int userId) {
24783 synchronized (mPackages) {
24784 final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
24785 return ps != null && !PackageManagerService.this.filterAppAccessLPr(
24786 ps, callingUid, component, TYPE_UNKNOWN, userId);
24791 public boolean hasInstantApplicationMetadata(String packageName, int userId) {
24792 synchronized (mPackages) {
24793 return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
24798 public void notifyPackageUse(String packageName, int reason) {
24799 synchronized (mPackages) {
24800 PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
24805 public CheckPermissionDelegate getCheckPermissionDelegate() {
24806 synchronized (mPackages) {
24807 return PackageManagerService.this.getCheckPermissionDelegateLocked();
24812 public void setCheckPermissionDelegate(CheckPermissionDelegate delegate) {
24813 synchronized (mPackages) {
24814 PackageManagerService.this.setCheckPermissionDelegateLocked(delegate);
24819 public SparseArray<String> getAppsWithSharedUserIds() {
24820 synchronized (mPackages) {
24821 return getAppsWithSharedUserIdsLocked();
24826 public String getSharedUserIdForPackage(String packageName) {
24827 synchronized (mPackages) {
24828 return getSharedUserIdForPackageLocked(packageName);
24833 public String[] getPackagesForSharedUserId(String sharedUserId, int userId) {
24834 synchronized (mPackages) {
24835 return getPackagesForSharedUserIdLocked(sharedUserId, userId);
24840 public boolean isOnlyCoreApps() {
24841 return PackageManagerService.this.isOnlyCoreApps();
24845 public void freeStorage(String volumeUuid, long bytes, int storageFlags)
24846 throws IOException {
24847 PackageManagerService.this.freeStorage(volumeUuid, bytes, storageFlags);
24851 public void forEachPackage(Consumer<PackageParser.Package> actionLocked) {
24852 PackageManagerService.this.forEachPackage(actionLocked);
24856 public void forEachInstalledPackage(@NonNull Consumer<PackageParser.Package> actionLocked,
24857 @UserIdInt int userId) {
24858 PackageManagerService.this.forEachInstalledPackage(actionLocked, userId);
24862 public ArraySet<String> getEnabledComponents(String packageName, int userId) {
24863 synchronized (mPackages) {
24864 PackageSetting setting = mSettings.getPackageLPr(packageName);
24865 if (setting == null) {
24866 return new ArraySet<>();
24868 return setting.getEnabledComponents(userId);
24873 public ArraySet<String> getDisabledComponents(String packageName, int userId) {
24874 synchronized (mPackages) {
24875 PackageSetting setting = mSettings.getPackageLPr(packageName);
24876 if (setting == null) {
24877 return new ArraySet<>();
24879 return setting.getDisabledComponents(userId);
24884 public @PackageManager.EnabledState int getApplicationEnabledState(
24885 String packageName, int userId) {
24886 synchronized (mPackages) {
24887 PackageSetting setting = mSettings.getPackageLPr(packageName);
24888 if (setting == null) {
24889 return COMPONENT_ENABLED_STATE_DEFAULT;
24891 return setting.getEnabled(userId);
24896 public void setEnableRollbackCode(int token, int enableRollbackCode) {
24897 PackageManagerService.this.setEnableRollbackCode(token, enableRollbackCode);
24901 * Ask the package manager to compile layouts in the given package.
24904 public boolean compileLayouts(String packageName) {
24905 PackageParser.Package pkg;
24906 synchronized (mPackages) {
24907 pkg = mPackages.get(packageName);
24912 return mArtManagerService.compileLayouts(pkg);
24916 public void finishPackageInstall(int token, boolean didLaunch) {
24917 PackageManagerService.this.finishPackageInstall(token, didLaunch);
24922 public String removeLegacyDefaultBrowserPackageName(int userId) {
24923 synchronized (mPackages) {
24924 return mSettings.removeDefaultBrowserPackageNameLPw(userId);
24929 public void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider) {
24930 synchronized (mPackages) {
24931 mDefaultBrowserProvider = provider;
24936 public void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider) {
24937 synchronized (mPackages) {
24938 mDefaultDialerProvider = provider;
24943 public void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider) {
24944 synchronized (mPackages) {
24945 mDefaultHomeProvider = provider;
24950 public boolean isApexPackage(String packageName) {
24951 return PackageManagerService.this.mApexManager.isApexPackage(packageName);
24955 public void uninstallApex(String packageName, long versionCode, int userId,
24956 IntentSender intentSender) {
24957 final int callerUid = Binder.getCallingUid();
24958 if (callerUid != Process.ROOT_UID && callerUid != Process.SHELL_UID) {
24959 throw new SecurityException("Not allowed to uninstall apexes");
24961 PackageInstallerService.PackageDeleteObserverAdapter adapter =
24962 new PackageInstallerService.PackageDeleteObserverAdapter(
24963 PackageManagerService.this.mContext, intentSender, packageName,
24965 if (userId != UserHandle.USER_ALL) {
24966 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
24967 "Can't uninstall an apex for a single user");
24970 final ApexManager am = PackageManagerService.this.mApexManager;
24971 PackageInfo activePackage = am.getPackageInfo(packageName,
24972 ApexManager.MATCH_ACTIVE_PACKAGE);
24973 if (activePackage == null) {
24974 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
24975 packageName + " is not an apex package");
24978 if (versionCode != PackageManager.VERSION_CODE_HIGHEST
24979 && activePackage.getLongVersionCode() != versionCode) {
24980 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
24981 "Active version " + activePackage.getLongVersionCode()
24982 + " is not equal to " + versionCode + "]");
24985 if (!am.uninstallApex(activePackage.applicationInfo.sourceDir)) {
24986 adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
24987 "Failed to uninstall apex " + packageName);
24989 adapter.onPackageDeleted(packageName, PackageManager.DELETE_SUCCEEDED,
24995 public boolean wereDefaultPermissionsGrantedSinceBoot(int userId) {
24996 synchronized (mPackages) {
24997 return mDefaultPermissionPolicy.wereDefaultPermissionsGrantedSinceBoot(userId);
25002 public void setRuntimePermissionsFingerPrint(@NonNull String fingerPrint,
25003 @UserIdInt int userId) {
25004 synchronized (mPackages) {
25005 mSettings.setRuntimePermissionsFingerPrintLPr(fingerPrint, userId);
25010 public void migrateLegacyObbData() {
25012 mInstaller.migrateLegacyObbData();
25013 } catch (Exception e) {
25019 @GuardedBy("mPackages")
25020 private SparseArray<String> getAppsWithSharedUserIdsLocked() {
25021 final SparseArray<String> sharedUserIds = new SparseArray<>();
25022 synchronized (mPackages) {
25023 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
25024 sharedUserIds.put(UserHandle.getAppId(setting.userId), setting.name);
25027 return sharedUserIds;
25030 @GuardedBy("mPackages")
25031 private String getSharedUserIdForPackageLocked(String packageName) {
25032 final PackageSetting ps = mSettings.mPackages.get(packageName);
25033 return (ps != null && ps.isSharedUser()) ? ps.sharedUser.name : null;
25036 @GuardedBy("mPackages")
25037 private String[] getPackagesForSharedUserIdLocked(String sharedUserId, int userId) {
25039 final SharedUserSetting sus = mSettings.getSharedUserLPw(
25040 sharedUserId, 0, 0, false);
25042 return EmptyArray.STRING;
25044 String[] res = new String[sus.packages.size()];
25045 final Iterator<PackageSetting> it = sus.packages.iterator();
25047 while (it.hasNext()) {
25048 PackageSetting ps = it.next();
25049 if (ps.getInstalled(userId)) {
25050 res[i++] = ps.name;
25052 res = ArrayUtils.removeElement(String.class, res, res[i]);
25056 } catch (PackageManagerException e) {
25057 // Should not happen
25059 return EmptyArray.STRING;
25063 public int getRuntimePermissionsVersion(@UserIdInt int userId) {
25064 Preconditions.checkArgumentNonnegative(userId);
25065 mContext.enforceCallingOrSelfPermission(
25066 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
25067 "setRuntimePermissionVersion");
25068 synchronized (mPackages) {
25069 return mSettings.getDefaultRuntimePermissionsVersionLPr(userId);
25074 public void setRuntimePermissionsVersion(int version, @UserIdInt int userId) {
25075 Preconditions.checkArgumentNonnegative(version);
25076 Preconditions.checkArgumentNonnegative(userId);
25077 mContext.enforceCallingOrSelfPermission(
25078 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
25079 "setRuntimePermissionVersion");
25080 synchronized (mPackages) {
25081 mSettings.setDefaultRuntimePermissionsVersionLPr(version, userId);
25086 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
25087 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
25088 synchronized (mPackages) {
25089 final long identity = Binder.clearCallingIdentity();
25091 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierApps(
25092 packageNames, userId);
25094 Binder.restoreCallingIdentity(identity);
25100 public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
25101 enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
25102 synchronized (mPackages) {
25103 final long identity = Binder.clearCallingIdentity();
25105 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServices(
25106 packageNames, userId);
25108 Binder.restoreCallingIdentity(identity);
25114 public void grantDefaultPermissionsToEnabledTelephonyDataServices(
25115 String[] packageNames, int userId) {
25116 enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledTelephonyDataServices");
25117 synchronized (mPackages) {
25118 Binder.withCleanCallingIdentity( () -> mDefaultPermissionPolicy.
25119 grantDefaultPermissionsToEnabledTelephonyDataServices(
25120 packageNames, userId));
25125 public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
25126 String[] packageNames, int userId) {
25127 enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromDisabledTelephonyDataServices");
25128 synchronized (mPackages) {
25129 Binder.withCleanCallingIdentity( () -> mDefaultPermissionPolicy.
25130 revokeDefaultPermissionsFromDisabledTelephonyDataServices(
25131 packageNames, userId));
25136 public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
25137 enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp");
25138 synchronized (mPackages) {
25139 final long identity = Binder.clearCallingIdentity();
25141 mDefaultPermissionPolicy.grantDefaultPermissionsToActiveLuiApp(
25142 packageName, userId);
25144 Binder.restoreCallingIdentity(identity);
25150 public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
25151 enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps");
25152 synchronized (mPackages) {
25153 final long identity = Binder.clearCallingIdentity();
25155 mDefaultPermissionPolicy.revokeDefaultPermissionsFromLuiApps(packageNames, userId);
25157 Binder.restoreCallingIdentity(identity);
25162 void forEachPackage(Consumer<PackageParser.Package> actionLocked) {
25163 synchronized (mPackages) {
25164 int numPackages = mPackages.size();
25165 for (int i = 0; i < numPackages; i++) {
25166 actionLocked.accept(mPackages.valueAt(i));
25171 void forEachInstalledPackage(@NonNull Consumer<PackageParser.Package> actionLocked,
25172 @UserIdInt int userId) {
25173 synchronized (mPackages) {
25174 int numPackages = mPackages.size();
25175 for (int i = 0; i < numPackages; i++) {
25176 PackageParser.Package pkg = mPackages.valueAt(i);
25177 PackageSetting setting = mSettings.getPackageLPr(pkg.packageName);
25178 if (setting == null || !setting.getInstalled(userId)) {
25181 actionLocked.accept(pkg);
25186 private static void enforceSystemOrPhoneCaller(String tag) {
25187 int callingUid = Binder.getCallingUid();
25188 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
25189 throw new SecurityException(
25190 "Cannot call " + tag + " from UID " + callingUid);
25194 boolean isHistoricalPackageUsageAvailable() {
25195 return mPackageUsage.isHistoricalPackageUsageAvailable();
25199 * Return a <b>copy</b> of the collection of packages known to the package manager.
25200 * @return A copy of the values of mPackages.
25202 Collection<PackageParser.Package> getPackages() {
25203 synchronized (mPackages) {
25204 return new ArrayList<>(mPackages.values());
25209 * Logs process start information (including base APK hash) to the security log.
25213 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
25214 String apkFile, int pid) {
25215 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
25218 if (!SecurityLog.isLoggingEnabled()) {
25221 Bundle data = new Bundle();
25222 data.putLong("startTimestamp", System.currentTimeMillis());
25223 data.putString("processName", processName);
25224 data.putInt("uid", uid);
25225 data.putString("seinfo", seinfo);
25226 data.putString("apkFile", apkFile);
25227 data.putInt("pid", pid);
25228 Message msg = mProcessLoggingHandler.obtainMessage(
25229 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
25231 mProcessLoggingHandler.sendMessage(msg);
25234 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
25235 return mCompilerStats.getPackageStats(pkgName);
25238 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
25239 return getOrCreateCompilerPackageStats(pkg.packageName);
25242 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
25243 return mCompilerStats.getOrCreatePackageStats(pkgName);
25246 public void deleteCompilerPackageStats(String pkgName) {
25247 mCompilerStats.deletePackageStats(pkgName);
25251 public int getInstallReason(String packageName, int userId) {
25252 final int callingUid = Binder.getCallingUid();
25253 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
25254 true /* requireFullPermission */, false /* checkShell */,
25255 "get install reason");
25256 synchronized (mPackages) {
25257 final PackageSetting ps = mSettings.mPackages.get(packageName);
25258 if (filterAppAccessLPr(ps, callingUid, userId)) {
25259 return PackageManager.INSTALL_REASON_UNKNOWN;
25262 return ps.getInstallReason(userId);
25265 return PackageManager.INSTALL_REASON_UNKNOWN;
25269 public boolean canRequestPackageInstalls(String packageName, int userId) {
25270 return canRequestPackageInstallsInternal(packageName, 0, userId,
25271 true /* throwIfPermNotDeclared*/);
25274 private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
25275 boolean throwIfPermNotDeclared) {
25276 int callingUid = Binder.getCallingUid();
25277 int uid = getPackageUid(packageName, 0, userId);
25278 if (callingUid != uid && callingUid != Process.ROOT_UID
25279 && callingUid != Process.SYSTEM_UID) {
25280 throw new SecurityException(
25281 "Caller uid " + callingUid + " does not own package " + packageName);
25283 ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
25284 if (info == null) {
25287 if (info.targetSdkVersion < Build.VERSION_CODES.O) {
25290 if (isInstantApp(packageName, userId)) {
25293 String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
25294 String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
25295 if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
25296 if (throwIfPermNotDeclared) {
25297 throw new SecurityException("Need to declare " + appOpPermission
25298 + " to call this api");
25300 Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
25304 if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)
25305 || sUserManager.hasUserRestriction(
25306 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, userId)) {
25309 if (mExternalSourcesPolicy != null) {
25310 int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
25311 return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
25317 public ComponentName getInstantAppResolverSettingsComponent() {
25318 return mInstantAppResolverSettingsComponent;
25322 public ComponentName getInstantAppInstallerComponent() {
25323 if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
25326 return mInstantAppInstallerActivity == null
25327 ? null : mInstantAppInstallerActivity.getComponentName();
25331 public String getInstantAppAndroidId(String packageName, int userId) {
25332 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
25333 "getInstantAppAndroidId");
25334 mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
25335 true /* requireFullPermission */, false /* checkShell */,
25336 "getInstantAppAndroidId");
25337 // Make sure the target is an Instant App.
25338 if (!isInstantApp(packageName, userId)) {
25341 synchronized (mPackages) {
25342 return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
25346 boolean canHaveOatDir(String packageName) {
25347 synchronized (mPackages) {
25348 PackageParser.Package p = mPackages.get(packageName);
25352 return p.canHaveOatDir();
25356 private String getOatDir(PackageParser.Package pkg) {
25357 if (!pkg.canHaveOatDir()) {
25360 File codePath = new File(pkg.codePath);
25361 if (codePath.isDirectory()) {
25362 return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
25367 void deleteOatArtifactsOfPackage(String packageName) {
25368 final String[] instructionSets;
25369 final List<String> codePaths;
25370 final String oatDir;
25371 final PackageParser.Package pkg;
25372 synchronized (mPackages) {
25373 pkg = mPackages.get(packageName);
25375 instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
25376 codePaths = pkg.getAllCodePaths();
25377 oatDir = getOatDir(pkg);
25379 for (String codePath : codePaths) {
25380 for (String isa : instructionSets) {
25382 mInstaller.deleteOdex(codePath, isa, oatDir);
25383 } catch (InstallerException e) {
25384 Log.e(TAG, "Failed deleting oat files for " + codePath, e);
25390 Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
25391 Set<String> unusedPackages = new HashSet<>();
25392 long currentTimeInMillis = System.currentTimeMillis();
25393 synchronized (mPackages) {
25394 for (PackageParser.Package pkg : mPackages.values()) {
25395 PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
25399 PackageDexUsage.PackageUseInfo packageUseInfo =
25400 getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
25401 if (PackageManagerServiceUtils
25402 .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
25403 downgradeTimeThresholdMillis, packageUseInfo,
25404 pkg.getLatestPackageUseTimeInMills(),
25405 pkg.getLatestForegroundPackageUseTimeInMills())) {
25406 unusedPackages.add(pkg.packageName);
25410 return unusedPackages;
25414 public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
25416 final int callingUid = Binder.getCallingUid();
25417 final int callingAppId = UserHandle.getAppId(callingUid);
25419 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
25420 true /*requireFullPermission*/, true /*checkShell*/, "setHarmfulAppInfo");
25422 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
25423 checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
25424 throw new SecurityException("Caller must have the "
25425 + SET_HARMFUL_APP_WARNINGS + " permission.");
25428 synchronized(mPackages) {
25429 mSettings.setHarmfulAppWarningLPw(packageName, warning, userId);
25430 scheduleWritePackageRestrictionsLocked(userId);
25436 public CharSequence getHarmfulAppWarning(@NonNull String packageName, int userId) {
25437 final int callingUid = Binder.getCallingUid();
25438 final int callingAppId = UserHandle.getAppId(callingUid);
25440 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
25441 true /*requireFullPermission*/, true /*checkShell*/, "getHarmfulAppInfo");
25443 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
25444 checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
25445 throw new SecurityException("Caller must have the "
25446 + SET_HARMFUL_APP_WARNINGS + " permission.");
25449 synchronized(mPackages) {
25450 return mSettings.getHarmfulAppWarningLPr(packageName, userId);
25455 public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) {
25456 final int callingUid = Binder.getCallingUid();
25457 final int callingAppId = UserHandle.getAppId(callingUid);
25459 mPermissionManager.enforceCrossUserPermission(callingUid, userId,
25460 false /*requireFullPermission*/, true /*checkShell*/, "isPackageStateProtected");
25462 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID
25463 && checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid) != PERMISSION_GRANTED) {
25464 throw new SecurityException("Caller must have the "
25465 + MANAGE_DEVICE_ADMINS + " permission.");
25468 return mProtectedPackages.isPackageStateProtected(userId, packageName);
25472 public void sendDeviceCustomizationReadyBroadcast() {
25473 mContext.enforceCallingPermission(Manifest.permission.SEND_DEVICE_CUSTOMIZATION_READY,
25474 "sendDeviceCustomizationReadyBroadcast");
25476 final long ident = Binder.clearCallingIdentity();
25478 final Intent intent = new Intent(Intent.ACTION_DEVICE_CUSTOMIZATION_READY);
25479 intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
25480 final IActivityManager am = ActivityManager.getService();
25481 final String[] requiredPermissions = {
25482 Manifest.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY,
25485 am.broadcastIntent(null, intent, null, null, 0, null, null, requiredPermissions,
25486 android.app.AppOpsManager.OP_NONE, null, false, false, UserHandle.USER_ALL);
25487 } catch (RemoteException e) {
25488 throw e.rethrowFromSystemServer();
25491 Binder.restoreCallingIdentity(ident);
25495 static class ActiveInstallSession {
25496 private final String mPackageName;
25497 private final File mStagedDir;
25498 private final IPackageInstallObserver2 mObserver;
25499 private final PackageInstaller.SessionParams mSessionParams;
25500 private final String mInstallerPackageName;
25501 private final int mInstallerUid;
25502 private final UserHandle mUser;
25503 private final SigningDetails mSigningDetails;
25505 ActiveInstallSession(String packageName, File stagedDir, IPackageInstallObserver2 observer,
25506 PackageInstaller.SessionParams sessionParams, String installerPackageName,
25507 int installerUid, UserHandle user, SigningDetails signingDetails) {
25508 mPackageName = packageName;
25509 mStagedDir = stagedDir;
25510 mObserver = observer;
25511 mSessionParams = sessionParams;
25512 mInstallerPackageName = installerPackageName;
25513 mInstallerUid = installerUid;
25515 mSigningDetails = signingDetails;
25518 public String getPackageName() {
25519 return mPackageName;
25522 public File getStagedDir() {
25526 public IPackageInstallObserver2 getObserver() {
25530 public PackageInstaller.SessionParams getSessionParams() {
25531 return mSessionParams;
25534 public String getInstallerPackageName() {
25535 return mInstallerPackageName;
25538 public int getInstallerUid() {
25539 return mInstallerUid;
25542 public UserHandle getUser() {
25546 public SigningDetails getSigningDetails() {
25547 return mSigningDetails;
25552 interface PackageSender {
25554 * @param userIds User IDs where the action occurred on a full application
25555 * @param instantUserIds User IDs where the action occurred on an instant application
25557 void sendPackageBroadcast(final String action, final String pkg,
25558 final Bundle extras, final int flags, final String targetPkg,
25559 final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds);
25560 void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
25561 boolean includeStopped, int appId, int[] userIds, int[] instantUserIds);
25562 void notifyPackageAdded(String packageName, int uid);
25563 void notifyPackageChanged(String packageName, int uid);
25564 void notifyPackageRemoved(String packageName, int uid);